Vue学习12–插槽
什么是插槽
插槽是子组件提供给父组件使用的一个占位符,用,父组件可以在这个占位符中填充任何模板代码,如HTML,组件等,填充的内容会替换子组件中的slot标签。相当于在子组件中放置了一个占位符,父组件传递进来的html片段会被加载到这个占位符的地方。
简单理解就是,在子组件内占坑,在父组件里填坑。 放在组件元素之间的html片段会被插槽占位符进行加载。
插槽如何使用
1、在子组件中使用插槽组件 指定插槽的名字:
2、使用方:在父组件引入的子组件元素之间直接添加需要传递的html片段:<组件标签> 传递hmtl片段 </组件标签>
还可以指定插槽名字,把html片段放置在指定插槽位置
1)<组件标签><div slot=“插槽名字”></组件标签>
2)<template v-slot:插槽名字=“接收到的数据”></template>
插槽传值:
子向父,插槽是一个slot标签,所以采用属性传值的方式传值
在父组件中使用,在组件元素之间插入html片段,有两种接收数据的方法:
1)slot-scope=“接收到的数据”
2)<template v-slot=“接收到的数据”></template>
注:
1) v-slot只能在template标签里使用,否者会报错。
2) 以上两种方式接收到的数据,都是传递过来对象封装的一个整体对象,哪怕只有一个传递的参数也要通过"."或中括号[]的方式去获取参数的值。
父向子,直接按照正常的父向子传递数据就行。
示例
父组件 index.vue
<template>
<div>
<list :columns="columns" :data="data">
<h3 slot="title">待办列表</h3>
<!-- v-slot只能在template标签里使用 -->
<template v-slot:state="state">
<span>
{{state.state}}
</span>
</template>
<div slot="opt" slot-scope="data">
<button v-if="data.state === '新增'" @click="clickEvt(data.id)">处理</button>
<button v-else @click="clickEvt(data.id)">激活</button>
</div>
</list>
</div>
</template>
<script>
import List from './component/List.vue'
export default {
components: { List },
comments:{List},
data(){
return {
columns:[
{key: 'title', name: '标题'},
{key: 'date', name: '时间'},
{key: 'handler', name: '处理人'},
{key: 'time', name: '完成时间'},
// 用状态来演示v-slot插槽传值
{slot: 'state', name: '状态'},
// 用操作来演示常规的指定插槽和插槽传值
{name: '操作'}
],
data:Array(10).fill("").map((_, i) => {
return {id:"id-" + i, title:"事件-" + i, handler:"zs", time:new Date(), date:"21-10-28", state:Math.random() > .5 ? "新增" : "完成"}
})
}
},
methods:{
clickEvt(id){
this.data.map(it => {
if(it.id === id){
if(it.state === "新增"){ it.state = "完成"}
else {it.state = "新增"}
return it
}
});
}
}
}
</script>
子组件 List.vue
<template>
<div>
<div>
<slot name="title"/>
</div>
<table>
<thead>
<tr>
<th v-for="col in columns" :key="col.key">{{col.name}}</th>
</tr>
</thead>
<tbody>
<tr v-for="row in data" :key="row.id">
<!-- 遍历标题栏的数组, 以标题栏数组的key值作为数据对象的key值(键名),这样来匹配让排盘不错乱 -->
<td v-for="col in columns" :key="col.key">
<!-- 当col.key的值存在时,就显示当前的值 -->
<div v-if="!!col.key">{{row[col.key]}}</div>
<div v-else-if="!!col.slot">
<slot name='state' :state="row.state"/>
</div>
<div v-else>
<slot name='opt' :id="row.id" :state="row.state"/>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props:{
columns:{
type:Array,
required:true
},
data:{
type:Array,
default:() =>[]
}
}
}
</script>