親子コンポーネント通信を解決する3つのVueスロット
プリアンブル
スロットはVueにとって非常に重要な部分だと思います。私が学習し実践している中では、コンポーネントとスロットを一緒に使うと、より効果的に機能します。また、より便利になることが多いです。
今日はVueのスロットのうち、デフォルトスロット、ネームドスロット、スコープドスロットの3種類を紹介します。
環境整備
最初にハッとするような初期環境を構築してみましょう。スロットを通して順を追って説明します。
は、これら3種類のデータをそれぞれレンダリングするカテゴリコンポーネントを書くことです。
カテゴリーコンポーネント
<template>
<div class="category">
<h1>{{title}}</h1>
<ul>
<li
v-for="(item,index) in listData"
:key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
props: {
listData:Array,
title: String
}
}
</script>
<style scoped>
.category{
width: 200px;
height: 300px;
background-color:pink;
}
</style>
アプリコンポーネント
<template>
<div id="app">
<Category :listData="games" :title="'Games'" />
<Category :listData="movies" :title="'Movies'" />
<Category :listData="foods" :title="'Foods'" />
</div>
</template>
<script>
import Category from '. /components/Category.vue'
export default {
name: 'App',
components: {
Category
},
data () {
return {
games:['Crossfire','qq飞车','Rock Kingdom'],
movies:['Hello, Lee Hwan Young','Youth Pie','Rush Hour'],
foods:['Shaoyang Rice Noodles','Changsha Cha Yan','Chongqing Hot Pot']
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
display: flex;
justify-content: space-between;
}
</style>
最初は上記のような要件でしたが、現在はビジネス要件が変わり、映画は1本だけ宣伝して他は宣伝しない、料理は1本だけ宣伝するプルになっています。
次の図のようになります。
どうすれば合うように変更できるのか?
Categoryコンポーネントにifを追加して1つずつ判断したほうがいいのでしょうか?それとも、もっと良い方法があるのでしょうか?
一つ一つやっていては、コードが非常に複雑になって読みづらくなるし、後でビジネス要件を変更したいときにコードを移動するのも簡単ではありません。
次はデフォルトスロットです。
I. デフォルトのスロット
propsでデータを受け取り、子コンポーネントでレンダリングを行うのではなく、スロットを定義するのです。
<template>
<div class="category">
<! -- Define slots, default content of slots -->
<slot> If this default </slot> is displayed when the parent component does not pass a value over;
</div>
</template>
<script>
export default {
props: {
}
}
</script>
アプリコンポーネントも変更
<template>
<div id="app">
<Category>
<h1>Games</h1>
<! -- <ul>
<li v-for="(item, index) in games" :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">
</Category>
<Category>
<h1>Movies</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) in movies" :key="index">{{ item }}</li> -->
<! -- </ul> -->
</Category>
<Category>
<h1>Foods</h1>
<ul>
<li v-for="(item, index) in foods" :key="index">{{ item }}</li>
</ul>
</Category>
<! -- look at what is displayed when we write nothing -- >
<Category>
</Category>
</div>
</template>
<script>
import Category from '. /components/Category.vue'
export default {
name: 'App',
components: {
Category
},
data () {
return {
games:['Crossfire','qq飞车','Rock Kingdom'],
movies:['Hello, Lee Hwan Young','Youth Pie','Rush Hour'],
foods:['Shaoyang Rice Noodles','Changsha Cha Yan','Chongqing Hot Pot']
}
}
}
</script>
表示効果。
説明します。
を書きました。
親コンポーネントに自閉とタグを書く代わりに、従来通り
注:CSSスタイルは、親コンポーネント、子コンポーネントのいずれに記述してもかまいません。子コンポーネントに書くということは、子コンポーネントに戻したときにレンダリングされるということです。
ここに書いた後、お客さんは急に「あなたはとてもパワフルだ、満足できない」と感じて、全部を渡すようになったのです。
次は、再びネーミングスロットの登場です。
ネームドスロット
1つのスロットを使って考えるのもすごいですが、試しに2つのスロットを使って考えてみてはどうでしょうか。
サブコンポーネントの変更
<template>
<div class="category">
<! -- must add the name in the parent component to specify which slot to put it in, which is why it's called a named slot --- >
<slot name="slot1"> If the parent component does not pass a value, this default </slot> is displayed;
<slot name="slot2"></slot>
</div>
</template>
<script>
export default {
props: {
}
}
</script>
親コンポーネント
<template>
<div id="app">
<Category>
<template slot="slot1">
<h1>Games</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"
/>
</template>
<template slot="slot2">
<button > qq登录</button>
<button > 微信登录</button>
</template>
</Category>
<Category>
<template slot="slot1">
<h1>Movies</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"
/>
</template>
<template slot="slot2">
<button > Click to buy tickets </button>
</template>
</Category>
<Category>
<template slot="slot1">
<h1>Foods</h1>
<ul>
<li v-for="(item, index) in foods" :key="index">{{ item }}</li>
</ul>
</template>
</Category>
<! -- look at what is displayed when we write nothing -- >
<Category> </Category>
</div>
</template>
<script>
import Category from '. /components/Category.vue'
export default {
name: 'App',
components: {
Category
},
data () {
return {
games:['Crossfire','qq飞车','Rock Kingdom'],
movies:['Hello, Lee Hwan-young','Youth Pie','RushExplanation.
We can put more than one slot in the component, but when there are more than one, we have to name them, and also specify them in the parent component so that they don't not fit in.
III. Scope slots
The scope slots are slightly different from the previous ones in that the data is in the parent component, while the scope slots are where the data is in the child component, which in turn is passed to the parent component to define the structure for rendering.
The modified child component
<template>
<div class="category">
<slot name="slot1"> If this default </slot> is displayed when the parent component does not pass a value over;
<slot name="slot2" :foods="foods"> If this default is displayed when the parent component is not passed over </slot>
</div>
</template>
<script>
export default {
data () {
return{
foods:['Shaoyang Rice Noodles','Changsha Cha Yan','Chongqing Hot Pot']
}
}
}
</script>
Parent component
<template>
<div id="app">
<Category>
<template slot="slot1">
<h1>Foods</h1>
</template>
<template slot="slot2" scope="listData">
<! --if you don't know, we can output it and see what it is- {{listData}} -->
<ul>
<li v-for="(item, index) in listData.foods" :key="index">
{{ item }}
</li>
</ul>
</template>
</Category>
<Category>
<template slot="slot1">
<h1>Foods</h1>
</template>
<template slot="slot2" scope="listData">
<ol>
<li v-for="(item, index) in listData.foods" :key="index">
{{ item }}
</li>
</ol>
</template>
</Category>
<Category>
<template slot="slot1">
<h1>Foods</h1>
</template>
<template slot="slot2" scope="listData">
<h4 v-for="(item, index) in listData.foods" :key="index">
{{ item }}
</h4>
</template>
</Category>
<Category>
<template slot="slot1" scope="listData">
{{listData}}
</template>
</Category>
</div>
</template>
<script>
import Category from '. /components/Category.vue'
export default {
name: 'App',
components: {
Category
}
}
</script>
rendering
I didn't think of any scenarios for this kind of use during my study and practice, but there are cases on the official website, so I think it must have a reason to exist, but my knowledge is too small to take advantage of it.
Explanation.
The child component passes a value to the parent component via :variable name="defined data" and the parent component receives it with , because there is still . layer before it reaches the
<template slot="slot2" scope="listData">
<! --if you don't know, we can output it and see what it is- {{listData}} -->
<ul>
<li v-for="(item, index) in listData.foods" :key="index">
{{ item }}
</li>
</ul>
</template>
summary
This is the end of this article, hope it can bring you help, also hope you can pay more attention to more content of the Codedevlib!
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueがechartsのtooltipにクリックイベントを追加するケーススタディ
-
Vue Element-uiは、アイコンを追加するためのツリーコントロールノードを詳細に実装しています。
-
vueネットワークリクエストソリューション ネイティブネットワークリクエストとjsネットワークリクエストライブラリ
-
Vueの要素ツリーコントロールに破線を追加する説明
-
元のイベントが実行されなかった後に要素を追加するためのjQueryソリューション
-
Vueにシンプルなメモ帳機能を実装
-
vueディレクティブv-bindの使用と注意点
-
vueにおけるv-forループオブジェクトのプロパティ
-
VUEグローバルフィルターの概念と留意点、基本的な使い方
-
Vueのクラススタイルの使い方の詳細