序言:slot是創建組件複用的強大工具,儘管不是很容易理解,我們來看一看slot是什麼以及如何在應用中使用它。
1、什麼是slot?
slot是vue組件的一種機制,允許你以嚴格父子關係以外的方式組合組件。slot爲你提供了將內容放置在新位置或使組件更加通用。理解它們最好的辦法就是通過實踐,我們以一個最簡單的例子開始:
<template>
<div>
<component-b>hello world</component-b>
</div>
</template>
<script>
import vue from 'vue'
const ComponentB = vue.component('component-b', {
template:`
<div><slot></slot></div>
`
});
export default {
data() {
return {
}
},
components: {
ComponentB
}
}
</script>
運行結果;
我們可以看到<component-b>標籤裏面的內容將會替換slot標籤,這就是所謂的內容分發,slot標籤起到的就是這個作用。
2、後備內容
後備內容是指當你沒有指定分發內容時,可以給slot指定一個內容。
<template>
<div>
<component-b>指定的分發內容</component-b>
<component-b></component-b>
</div>
</template>
<script>
import vue from 'vue'
const ComponentB = vue.component('component-b', {
template:`
<div><slot>我是一個默認值</slot></div>
`
});
export default {
data() {
return {
}
},
components: {
ComponentB
}
}
</script>
運行結果:
3、多個具名插槽
您可以向組件添加多個插槽,但如果這樣做,則除了其中一個插槽之外的所有插槽都需要具有名稱。如果沒有名稱,則爲默認插槽。以下是創建多個插槽的方法:
<template>
<div>
<component-b>
<template v-slot:top>我是頂部</template>
<p>我是主體一</p>
<p>我是主題二</p>
<template v-slot:bottom>我是底部</template>
</component-b>
</div>
</template>
<script>
import vue from 'vue'
const ComponentB = vue.component('component-b', {
template:`
<div>
<slot name="top"></slot>
<slot></slot>
<slot name="bottom"></slot>
</div>
`
});
export default {
data() {
return {
}
},
components: {
ComponentB
}
}
</script>
運行結果:
4、插槽作用域
舉個例子,比如我寫了一個可以實現條紋相間的列表組件,發佈後,使用者可以自定義每一行的內容或樣式(普通的slot就可以完成這個工作)。而作用域插槽的關鍵之處就在於,父組件能接收來自子組件的slot傳遞過來的參數,具體看案例和註釋。
<template>
<div>
<component-b :items="user" oddBackgroudColor="#D3DCE6" evenBackgroudColor="#E5E9F2">
<template v-slot:list="props">
/*通過props對象接收子組件插槽傳過來的參數*/
<span>{{user[props.$index].id}}</span>
<span>{{user[props.$index].name}}</span>
<span>{{user[props.$index].age}}</span>
</template>
</component-b>
</div>
</template>
<script>
import vue from 'vue'
const ComponentB = vue.component('component-b', {
data() {
return {
}
},
template:`
<ul>
<li v-for="(item, index) in items" style="line-height:2.2;list-style-type:none" :style="index % 2 === 0?'background-color:' + oddBackgroudColor:'background-color:' + evenBackgroudColor">
/*slot的$index可以傳遞到父組件中*/
<slot name="list" :$index="index"></slot>
</li>
</ul>
`,
props:{
items:Array,
oddBackgroudColor:String,
evenBackgroudColor:String
}
});
export default {
data() {
return {
"user":[
{id: 1, name: '張三', age: 20},
{id: 2, name: '李四', age: 22},
{id: 3, name: '王五', age: 27},
{id: 4, name: '張龍', age: 27},
{id: 5, name: '趙虎', age: 27}
]
}
},
components: {
ComponentB
}
}
</script>