序言: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>