親子コンポーネントの通信を解決するための3つのVueスロット

親子コンポーネントの通信を解決するための3つのVueスロット

序文

スロットは Vue の非常に重要な部分と言えます。学習と実践の過程で、コンポーネントをスロットと一緒に使用すると、パフォーマンスが向上することがわかりました。より多くの時間、より便利になるでしょう。

今日は、Vue の 3 種類のスロット、デフォルト スロット、名前付きスロット、スコープ スロットを紹介します。

環境の準備

まず、全員が確認できるように初期環境を設定しましょう。このスロットについて段階的に説明しましょう。

これら 3 種類のデータをそれぞれレンダリングするには、カテゴリ コンポーネントを記述するだけです。

画像-20211120150949138

カテゴリコンポーネント

<テンプレート>
  <div class="カテゴリ">
    <h1>{{タイトル}}</h1>
    <ul>
      <li 
      v-for="(item,index) in listData"
      :key="index">{{item}}</li>
    </ul>
  </div>
</テンプレート>
<スクリプト>
エクスポートデフォルト{
  小道具: {
    リストデータ:配列、
    タイトル: 文字列
  }
}
</スクリプト>
<スタイルスコープ>
。カテゴリ{
  幅: 200ピクセル;
  高さ: 300px;
  背景色:ピンク;
}
</スタイル>

アプリのコンポーネント

<テンプレート>
  <div id="アプリ">
    <Category :listData="ゲーム" :title="'ゲーム'" />
    <Category :listData="映画" :title="'映画'" />
    <Category :listData="食品" :title="'食品'" />
  </div>
</テンプレート>
<スクリプト>
'./components/Category.vue' からカテゴリーをインポートします。
エクスポートデフォルト{
  名前: 'アプリ'、
  コンポーネント:
    カテゴリ
  },
  データ () {
    戻る {
      ゲーム:['クロスファイア','QQスピード','ロックキングダム'],
      映画:[『こんにちは、李華英』、『青春』、『つかの間の時間』]、
      食べ物:['邵陽米麺'、'長沙茶'、'重慶火鍋']
    }
  }
}
</スクリプト>
<スタイル>
#アプリ {
  フォントファミリー: Avenir、Helvetica、Arial、sans-serif;
  -webkit-font-smoothing: アンチエイリアス;
  -moz-osx-font-smoothing: グレースケール;
  テキスト配置: 中央;
  色: #2c3e50;
  上マージン: 60px;
  ディスプレイ: フレックス;
  コンテンツの両端揃え: スペースの間;
}
</スタイル>

当初の要件は上の写真のとおりでしたが、現在ではビジネス要件が変わりました。映画はそのうちの 1 つだけを宣伝し、他のものは宣伝していません。食べ物もそのうちの 1 つだけを宣伝しています。

以下のように表示されます。

画像-20211120151432264

どうすれば適切にできるでしょうか?

カテゴリ コンポーネントに if ステートメントを追加して、1 つずつ判断を下していますか?それとももっと良い方法があるのでしょうか? ? ?

一つ一つ判断するのは不可能で、コードが非常に複雑になり、読みにくくなります。将来、業務要件の変更が必要になった場合、コードの変更が困難になります。

次に、デフォルトのスロットを見てみましょう。

1. デフォルトスロット

データを受信したり子コンポーネントでレンダリングしたりするために props を使用する必要はなくなり、代わりにスロットを定義します。

<テンプレート>
<div class="カテゴリ">
    <!-- スロット、スロットのデフォルト コンテンツを定義 -->
    <slot>親コンポーネントが値を渡さない場合は、このデフォルトが表示されます</slot>
    </div>
</テンプレート>
<スクリプト>
    エクスポートデフォルト{
        小道具: {
        }
    }
</スクリプト>

アプリのコンポーネントも変更されました

<テンプレート>
<div id="アプリ">
    <カテゴリー>
        <h1>ゲーム</h1>
        <!-- <ul>
<li v-for="(item, index) ゲーム内" :key="index">{{ item }}</li>
    </ul> -->
        <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fb352264fa7bfdb6d211f2e71e87cc2c48d85b805.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931135&t=0b2c6c622c84a1e387196cce8f50455e">
    </カテゴリー>
    
    <カテゴリー>
        <h1>映画</h1>
        <img class="movies" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13236694597%2F641.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931502&t=f89c2197bda9bb129d9404d3c4b30f2f">
        <!-- <ul> -->
        <!-- <li v-for="(item, index) 映画内" :key="index">{{ item }}</li> -->
        <!-- </ul> -->
    </カテゴリー>
    <カテゴリー>
        <h1>食品</h1>
        <ul>
            <li v-for="(item, index) 食品内" :key="index">{{ item }}</li>
    </ul>
    </カテゴリー>
    
    <!-- 何も書いていないときに何が表示されるか確認します -->
    <カテゴリー>
    </カテゴリー>
    </div>
</テンプレート>
 
<スクリプト>
    './components/Category.vue' からカテゴリーをインポートします。
 
    エクスポートデフォルト{
        名前: 'アプリ'、
        コンポーネント:
            カテゴリ
        },
        データ () {
            戻る {
                ゲーム:['クロスファイア','QQスピード','ロックキングダム'],
                映画:[『こんにちは、李華英』、『青春』、『つかの間の時間』]、
                食べ物:['邵陽米麺'、'長沙茶'、'重慶火鍋']
            }
        }
    }
</スクリプト>

表示効果:

画像-20211120152024922

説明する:

子コンポーネントに <slot>親コンポーネントが値を渡さない場合は、このデフォルトを表示する</slot> タグを記述しました。これは、位置を占有することと同じです。

親コンポーネントでは、以前のように自己終了とタグ <Category/> を記述せず、代わりに非自己終了とタグ <Category> content</Category> を記述します。こうすることで、Vue はデフォルトでコンポーネント タグに記述されたコンテンツをレンダリングし、それを子コンポーネントの <slot></slot> に戻します。

注: CSS スタイルはレンダリング後に子コンポーネントに戻されるため、親コンポーネントまたは子コンポーネントのどちらにも記述できます。子コンポーネントに記述すると、子コンポーネントに戻されたときにレンダリングされます。

これを書いた後、クライアントは突然あなたがとても有能だと思い、不満になり、再びあなたに迷惑をかけ始めます。

画像-20211120152906020

次に、名前付きスロットが表示されます。

2. 名前付きスロット

1 つのスロットを使用することは考えられるので、2 つのスロットを使用してみることはできないでしょうか?

サブコンポーネントの変換

<テンプレート>
  <div class="カテゴリ">
    <!-- 親コンポーネントに名前を付けて、どのスロットに配置するかを指定する必要があります。これが名前付きスロットと呼ばれる理由です--->
    <slot name="slot1">親コンポーネントが値を渡さない場合は、このデフォルトが表示されます</slot>
    <スロット名="スロット2"></スロット>
  </div>
</テンプレート>
<スクリプト>
エクスポートデフォルト{
  小道具: {
  }
}
</スクリプト>

親コンポーネント

<テンプレート>
	<div id="アプリ">
    	<カテゴリー>
       	 <テンプレートスロット="スロット1">
          	  <h1>ゲーム</h1>
            <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi0.hdslb.com%2Fbfs%2Farticle%2Fb352264fa7bfdb6d211f2e71e87cc2c48d85b805.jpg&refer=http%3A%2F%2Fi0.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931135&t=0b2c6c622c84a1e387196cce8f50455e"
                 />
	</テンプレート>
	<テンプレートスロット="スロット2">
		<button >qq ログイン</button>
		<button >WeChatでログイン</button>
	</テンプレート>
 
</カテゴリー>
<カテゴリー>
    <テンプレートスロット="スロット1">
		<h1>映画</h1>
			<画像
     クラス="映画"
     src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13236694597%2F641.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1639931502&t=f89c2197bda9bb129d9404d3c4b30f2f"
     />
    </テンプレート>
    <テンプレートスロット="スロット2">
		<button >クリックしてチケットを購入</button>
    </テンプレート>
</カテゴリー>
 
<カテゴリー>
    <テンプレートスロット="スロット1">
		<h1>食品</h1>
		<ul>
    		<li v-for="(item, index) 食品内" :key="index">{{ item }}</li>
        </ul>
    </テンプレート>
</カテゴリー>
 
<!-- 何も書いていないときに何が表示されるか確認します -->
<カテゴリー> </カテゴリー>
</div>
</テンプレート>
 
<スクリプト>
    './components/Category.vue' からカテゴリーをインポートします。
 
    エクスポートデフォルト{
        名前: 'アプリ'、
        コンポーネント:
            カテゴリ
        },
        データ () {
            戻る {
                ゲーム:['クロスファイア','QQスピード','ロックキングダム'],
                映画:[『こんにちは、李華英』、『青春』、『つかの間の時間』]、
                食べ物:['邵陽米麺'、'長沙茶'、'重慶火鍋']
            }
        }
    }
</スクリプト>

エフェクト表示

画像-20211120153500451

説明する:

コンポーネントに複数のスロットを配置できますが、複数のスロットがある場合は、欠落しないように親コンポーネントで名前を付けて指定する必要があります。

3. スコープ付きスロット

スコープ付きスロットは、以前のものとは少し異なります。以前は、データは親コンポーネントにありましたが、スコープ付きスロットは子コンポーネントにあり、それが親コンポーネントに渡され、親コンポーネントがレンダリングの構造を定義できるようになりました。

変更されたサブコンポーネント

<テンプレート>
  <div class="カテゴリ">
    <slot name="slot1">親コンポーネントが値を渡さない場合は、このデフォルトが表示されます</slot>
    <slot name="slot2" :foods="foods">親コンポーネントが値を渡さない場合は、このデフォルト値が表示されます</slot>
  </div>
</テンプレート>
<スクリプト>
エクスポートデフォルト{
  データ () {
    戻る {
      食べ物:['邵陽米麺'、'長沙茶'、'重慶火鍋']
    }
  }
}
</スクリプト>

親コンポーネント

<テンプレート>
  <div id="アプリ">
    <カテゴリー>
      <テンプレートスロット="スロット1">
        <h1>食品</h1>
      </テンプレート>
      <テンプレート スロット="スロット2" スコープ="リストデータ">
        <!-- わからない場合は、これが何であるかを出力できます。 {{listData}} -->
        <ul>
          <li v-for="(item, index) in listData.foods" :key="index">
            {{ アイテム }}
          </li>
        </ul>
      </テンプレート>
    </カテゴリー>
    <カテゴリー>
      <テンプレートスロット="スロット1">
        <h1>食品</h1>
      </テンプレート>
      <テンプレート スロット="スロット2" スコープ="リストデータ">
        <オル>
          <li v-for="(item, index) in listData.foods" :key="index">
            {{ アイテム }}
          </li>
        </ol>
      </テンプレート>
    </カテゴリー>
    <カテゴリー>
      <テンプレートスロット="スロット1">
        <h1>食品</h1>
      </テンプレート>
      <テンプレート スロット="スロット2" スコープ="リストデータ">
          <h4 v-for="(item, index) in listData.foods" :key="index">
            {{ アイテム }}
          </h4>
      </テンプレート>
    </カテゴリー>
    <カテゴリー>
      <テンプレート スロット="スロット1" スコープ="リストデータ">	
{{リストデータ}}
      </テンプレート>
    </カテゴリー>
  </div>
</テンプレート>
 
<スクリプト>
'./components/Category.vue' からカテゴリーをインポートします。
 
エクスポートデフォルト{
  名前: 'アプリ'、
  コンポーネント:
    カテゴリ
  }
}
</スクリプト>

レンダリング

画像-20211120154438477

学習や実践の中ではこのような活用シーンは思い浮かばなかったのですが、公式サイトには事例が載っていました。存在意義があるんだろうなとは思うのですが、知識が足りず、活用できていません。

説明する:

子コンポーネントは、変数名 = "定義されたデータ"を介して親コンポーネントに値を渡します。親コンポーネントは、子コンポーネントに到達する前にもう1つのレイヤーがあるため、<template slot = "slot2" scope = "子コンポーネントによって渡された名前と同じ名前を使用しない">でそれを受け取ります。

<テンプレート スロット="スロット2" スコープ="リストデータ">
<!-- わからない場合は、これが何であるかを出力できます。 {{listData}} -->
<ul>
    <li v-for="(item, index) in listData.foods" :key="index">
        {{ アイテム }}
    </li>
    </ul>
</テンプレート>

要約する

この記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。

以下もご興味があるかもしれません:
  • Vue3の7つのコンポーネント通信方式の詳細説明
  • Vue3における7種類のコンポーネント通信の詳細
  • Vueコンポーネント通信方法事例まとめ
  • Vue がコンポーネント通信を実装する 8 つの例
  • Vue におけるコンポーネント通信の詳細説明 (父子コンポーネント、祖父孫コンポーネント、兄弟コンポーネント)
  • Vueコンポーネント間の通信方法はいくつかある

<<:  HTML リンク アンカー タグと SEO におけるその役割の概要

>>:  アクセス速度を上げるためにウェブサイトを最適化する方法の更新

推薦する

MySQLデータのバックアップ方法の選択と考え方

目次1. rsync、cpでファイルをコピーする2. xxxをoutfile構文に選択する3. 遅延...

crontab でスケジュールされたタスクが実行されない理由の概要

序文最近、仕事でいくつかの問題が発生しました。crontab でスケジュールされたタスクが実行されま...

MySQLデータベースのストアドプロシージャとトランザクションの違い

トランザクションは、複数の SQL ステートメントの原子性、つまり、それらが一緒に完了するか、一緒に...

MySQL データベース 8 - データベース内の関数の適用の詳細な説明

データベースの組み込み関数の使用この記事では、主に日付関数、文字列関数、数学関数など、データベースの...

MySQL の選択、挿入、更新バッチ操作ステートメントのコード例

プロジェクトでは、データを操作するためにバッチ操作ステートメントが必要になることがよくあります。バッ...

Mac で MySQL バージョン 5.6 のパスワードを設定する方法

MySQLはインストール時に設定できますが、それより低いバージョンは設定できないようで、インストール...

Dockerボリュームコンテナ間のデータ共有の実装

ボリュームとは何ですか?ボリュームは英語で容量を意味し、Docker ではデータ ボリューム、つまり...

Reactの基本のまとめ

目次序文始めるReactライフサイクルリアクトファイバーリアクトセットステートReactイベントメカ...

vmware workstation12 インストール CentOS プロンプト VMware Player と Device/Credential Guard に互換性がない、理由と解決策

最新バージョンの WIN10 では、Microsoft は仮想化コンテナに基づくセキュリティ メカニ...

Docker管理に関する断片的な知識のまとめ

目次1. 概要2. 応用例2.1、Docker コンテナ分離名前空間2.2. Docker のフリー...

W3C が推奨するモバイル Web マークアップ言語 XHTML Basic 1.1

W3C は最近、「 XHTML Basic1.1 」と「 Mobile Web Best Prac...

dockerコマンドの使用にはsudoは必要ありません

docker デーモンは通常の TCP ポートではなくホストの Unix ソケットにバインドする必要...

show processlist コマンドによる MySQL パフォーマンス検査の説明

show processlist コマンドは非常に便利です。MySQL の実行が 50% 以上になる...

JS を使用して航空機戦争の小さなゲームを実装する

この記事の例では、参考のために航空機戦争ゲームを実装するためのJSの具体的なコードを共有しています。...

複数のサーバーにNginxリバースプロキシを実装する方法

Nginx は複数のサーバーをリバース プロキシします。つまり、nginx に異なるリクエストを送信...