所謂組件的插槽,簡單來說就是在子組件中預留一定的位置,父組件可以向該位置傳遞內容。
基本插槽
子組件預留的位置:
<slot>默認內容</slot>
父組件向子組件分發內容
<!-- 組件包着的內容就是向子組件分發的內容 -->
<組件名稱>要分發的內容</組件名稱>
基本例子
<div id="test">
<!-- 使用組件 -->
<!-- 如果使用子組件的時候沒有傳遞數據,則使用子組件插槽的默認內容 -->
<btn></btn>
<!-- 如果使用子組件的時候傳遞有數據,則使用父組件傳遞的內容 -->
<btn>這是我的按鈕</btn>
</div>
<script src="./vue.js"></script>
<script>
Vue.component('btn', {
// 通過<slot></slot>預留插槽
template: `<button><slot>按我</slot></button>`
})
new Vue({
el: '#test'
})
</script>
具名插槽
所謂具名插槽,就是指有名字的插槽,就是子組件在預留插槽位置的時候,可以設置插槽的名字,父組件在向子組件分發內容的時候,可以根據名字向不同的插槽分別分發內容
<div id="test">
<xxx>你好嗎</xxx>
<div>****************</div>
<xxx>
<span slot="boy">學習Java從入門到放棄</span>
<span slot="girl">數據庫從刪庫到跑路/span>
<span slot="boy">學習Vue從入門到大神</span>
66666
</xxx>
</div>
<script src="./vue.js"></script>
<script>
Vue.component('xxx', {
// 通過<slot></slot>預留插槽
template: `<div>
<div style="color: green;">
<slot name="boy"></slot>
</div>
<div style="color: pink;">
<slot name="girl"></slot>
</div>
<div style="color: blue;">
<slot></slot>
</div>
</div>`
})
new Vue({
el: '#test'
})
</script>
從上面的例子我們可以看出,組件在預留插槽的時候是這樣的:
<div>
<div style="color: green;">
<!-- 名字爲boy的插槽 -->
<slot name="boy"></slot>
</div>
<div style="color: pink;">
<!-- 名字爲girl的插槽 -->
<slot name="girl"></slot>
</div>
<div style="color: blue;">
<!-- 沒名字的插槽 -->
<slot></slot>
</div>
</div>
父組件向子組件分發內容是這樣的:
<div id="test">
<xxx>你好啊</xxx>
<div>****************</div>
<xxx>
<span slot="boy">喫飯</span>
<span slot="girl">睡覺</span>
<span slot="boy">打豆豆</span>
666
</xxx>
</div>
分發規則就是:父組件分發內容時,是按照名字分發到對應的插槽中,如果分發的內容沒有名字,就是分發到無名字的子組件插槽。
使用template標籤進行批量具名分發
對於一次性需要分發的內容比較多的時候,可以使用一個叫template的標籤,一塊分發。
<div id="test">
<xxx>
<!-- 對於多個,我們可以使用一個固定的template標籤進行分發 -->
<template slot="boy">
<span>喫飯</span>
<span>睡覺</span>
</template>
<span slot="girl">打豆豆</span>
666
</xxx>
</div>
作用域插槽
作用域插槽一般用在子組件的內容需要在父組件中處理的時候。
<div id="test">
<xxx>
<!-- sonData是子組件綁定的數據,名字可以自己定 -->
<template slot-scope="sonData">
<span v-if="sonData.king.camp == '蜀國大帝'" style="color: red;">{{sonData.king.name}} --- {{sonData.king.camp}}</span>
<span v-else>{{sonData.king.name}} --- {{sonData.king.camp}}</span>
</template>
</xxx>
</div>
<script src="./vue.js"></script>
<script>
Vue.component('xxx', {
data() {
return {
kings: [
{name: '曹操', camp: '魏國大帝'},
{name: '孫權', camp: '吳國大帝'},
{name: '劉備', camp: '蜀國大帝'},
]
}
},
template: `<ul>
<!-- 子組件定義插槽的同時,綁定一個屬性(名字自定),綁定的數據可以被父組件捕獲到 -->
<li v-for="i in kings"><slot :king="i">{{i.name}}</slot></li>
</ul>`
})
new Vue({
el: '#test'
})
</script>
從例子中我們可以看出,在子組件中定義插槽的時候,可以綁定一個屬性(名字自定),該屬性綁定的數據可以被父組件捕獲到。
template: `<ul><li v-for="i in kings"><slot :king="i">{{i.name}}</slot></li></ul>`
在父組件中,可以通過 slot-scope
屬性捕獲到子組件綁定的數據,然後我們就可以自由的修改數據,修改後的數據會再次分發到子組件中
<xxx>
<!-- sonData是子組件綁定的數據,名字可以自己定 -->
<template slot-scope="sonData">
<!--這裏的king就是子組件綁定的屬性名,這個要一致-->
<span v-if="sonData.king.camp =='蜀國大帝'" style="color:red;">{{sonData.king.name}}</span>
<span v-else>{{sonData.king.name}}</span>
</template>
</xxx>