親子コンポーネントの通信を解決するための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 におけるその役割の概要

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

推薦する

WeChatアプレットは画像コントロールを選択します

この記事の例では、WeChatアプレットで画像コントロールを選択するための具体的なコードを参考までに...

MySQL 5.7.13 winx64 のインストールと設定方法のグラフィック チュートリアル (win10)

この記事では、参考までにMySQL 5.7.13 winx64のインストールと設定方法のグラフィック...

JavaScript ドラッグタイム ドラッグケースの詳細な説明

目次DragEvent インターフェースデータ転送インターフェースの概要DataTransfer の...

Vue+nodeはオーディオ録音・再生機能を実現

結果: コードロジックを実装するのが主な部分であり、具体的なページ構造を一つ一つ紹介することはありま...

MySqlのインストールとアンインストールに関する詳細なチュートリアル

この記事では、MySqlのインストールとアンインストールのチュートリアルを参考までに紹介します。具体...

ZabbixはLinuxシステムサービスのプロセスを監視

Zabbix は Linux システムのサービス ユニットを監視するためのルールを自動的に検出します...

Vue3でカルーセルコンポーネントをカプセル化する方法

目的カルーセルコンポーネントをカプセル化して直接使用します。具体的な内容は以下のとおりです。一般的な...

初心者がdockerにmysqlをインストールするときに遭遇するさまざまな問題

序文最近、パソコンのシャットダウンに時間がかかることが多く、強制的にシャットダウンするには電源ボタン...

Vue3 でサードパーティのコンポーネントライブラリをオンデマンドでロードする方法

序文Element Plus を例に、コンポーネントとスタイルのオンデマンド読み込みを構成します。環...

JSはユーザー登録インターフェース機能を実装します

この記事の例では、ユーザー登録インターフェース機能を実装するためのJSの具体的なコードを参考までに共...

MySQLを閉じることができない問題を解決する方法

mysql が閉じない場合の解決策:コンピュータのタスクバーを右クリックしてタスクマネージャーを開き...

MySQL 分離列とプレフィックスインデックスの使用の概要

目次データ列を分離するプレフィックスインデックスとインデックスの選択性データ列を分離するMySQL ...

mysqlのデータディレクトリ内のファイルを直接コピーしてデータを復元する実装

mysqlはデータディレクトリ内のファイルをコピーしてデータを復元します背景: MySQL がクラッ...

Mac ノードの削除と再インストールのケーススタディ

Macノードの削除と再インストール消去 ノード -v sudo npm アンインストール npm -...

Docker での MySQL 8.0.20 のインストールと設定のチュートリアル

Dockerは参考までにMySQLバージョン8.0.20をインストールします。具体的な内容は以下のと...