所谓组件的插槽,简单来说就是在子组件中预留一定的位置,父组件可以向该位置传递内容。
基本插槽
子组件预留的位置:
<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>