携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
1.什么是插槽?
插槽的关键字slot,默认情况下,组件中的模板会覆盖组件中的原始内容(即自定义标签对内部的内容会不显示)
组件的原始内容: 即在vue实例范围之内,因此可以调用实例的data和methods
好处:让组件使用更灵活, 功能更强大, 复用性更强,让组件内的部分标签支持自定义
使用场景:比如布局组件、表格列、下拉选、弹框显示内容等
比如我们项目中经常会使用到一个多处复用的组件,但是在每个地方使用时,都需要一些细微的更改,只需使用插槽向需要微调的位置传递内容,就能让这个组件在不同场景下应用
简单说就是可以对复用组件的私人定制!
2.插槽的分类
插槽总共分为三类:
匿名插槽
具名插槽
作用域插槽
3.默认插槽
默认插槽就是指没有名字的插槽,子组件未定义的名字的插槽,父级将会把指定插槽的填充的内容填充到默认插槽中
default,可以省略default直接写v-slot
先上效果:
- 在子组件中使用 占位
<template>
<div>
<h3>世界各地菠萝价格</h3>
<img src="./菠萝.png">
<slot></slot>
</div>
</template>
<style>
img {
width: 5%;
height: 5%;
}
</style>
2.在父组件中给这个占位符填充内容
<template>
<div>
<div>
<Son> <div>缅甸88一斤</div></Son>
<Son><div>泰国99一斤</div></Son>
</div>
</div>
</template>
<script>
import Son from "./Son.vue";
export default {
components: { Son },
};
</script>
4.具名插槽
具名插槽其实就是给插槽取个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。可以让组件内有多处自定义标签的能力
如果slot没有name属性,就是默认插槽,而父组件中不指定slot属性的内容,就会被丢到匿名插槽中。
v-slot可以简写为 #,但是必须写参数
1. 在子组件中使用 占位, 并设置 name 属性
<template>
<div>
<h3>世界各地菠萝价格</h3>
<img src="../菠萝.png" />
<slot name="noe"></slot>
<slot name="two"></slot>
</div>
</template>
<style>
img {
width: 5%;
height: 5%;
}
</style>
2. 在父组件中给这个占位符填充内容
<template>
<div>
<Son>
<div slot="noe">
缅甸88一斤!真好吃
</div>
</Son>
<Son>
<div slot="two">
泰国99一斤
</div>
</Son>
</div>
</template>
<script>
import Son from "./Son.vue";
export default {
components: { Son },
};
</script>
5.作用域插槽
作用域插槽就是带数据的插槽
可以在使用组件时访问组件内的数据
子组件在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件v-slot接受的对象上
先上效果图:
使用方法
1. 在子组件中使用 占位, 并使用 v-bind 绑定数据给 slot 标签
<template>
<div>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>品名</th>
<th>图片</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in arr" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td><slot name="one"></slot></td>
<td>
<!-- 定义插槽 -->
<slot :row="item"></slot>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: { arr: Array },
};
</script>
<style scoped>
td {
height: 70px;
}
</style>
2. 父组件使用组件时, 在 标签上使用 v-slot="变量名" 取值使用
<template>
<div>
<Son :arr="list">
<!-- 具名插槽传递图片 -->
<template slot="one">
<img src="../菠萝.png" width="60px" />
</template>
<!-- 传递button展示 -->
<template v-slot="scope">
<button @click="del(scope.row.id)">删除</button>
</template>
</Son>
</div>
</template>
<script>
import Son from "./Son.vue";
export default {
components: {
Son,
},
data() {
return {
list: [
{
id: "1",
name: "小菠萝",
},
{
id: "2",
name: "中菠萝",
},
{
id: "3",
name: "大菠萝",
},
],
};
},
methods: {
del(id) {
alert(id);
},
},
};
</script>