1. slot 插槽的概念
插槽相当于一个占位符,可以把父组件里的内容渲染到子组件里面
2. slot 插槽的分类
- 具名插槽: 给插槽取个名字,一个萝卜一个坑,子组件中slot标签通过name属性给插槽命名,
在父组件通过
#name或v-slot:name或v-slot="name"来决定渲染到哪个slot标签中
- 可传参插槽:slot标签,除了name属性是被占用的,传入的其他属性可以作为变量传递给使用插槽的地方,父组件可以使用
#name="scope"或v-slot:name="scope"来接受,scope就是传递过来的参数,是一个Object对象,key名就是slot标签的属性名
- 动态具名插槽:插槽的名字可以使用变量。slot标签中使用
:name="xxx"来取名,父组件中使用#[xxx]或v-slot:[xxx]
子组件中获取所有父组件传过来的插槽
Vue2使用this.$slots
Vue3在setup函数中使用context.$slot,<script setup>标签里面使用useSlots()方法
// Vue2
this.$slots
// Vue3
<script>
setup(data, ctx){
ctx.$slots
}
<script setup>
</script>
import {useSlots} from 'vue'
const slots = useSlots()
</script>
总结
讲了这么多,主要是为了引出动态具名插槽概念,可以给插槽取一个变量作为名字,父组件可以动态给具名插槽赋值,极大的方便了我们嵌套多层的组件,插槽传递的问题。
简单描述一个适用场景吧:三个组件A,B,C,他们的关系A->B->C,即A嵌套在B里面,B嵌套在C组件里。A组件里面通过props接收插槽的名字,B组件是一个中间组件,C组件会把插槽的名字传递给B,B再传递给C,那么B组件怎么把接收到的C组件中插槽的内容传递给A组件呢,就可以使用动态具名插槽了,实现方法如下
// 组件A-子组件
<div>
<slot v-for="item in slots" :key="item":name="item">
</slot>
<div>
// 组件B-中间组件
<A-comp :slots="slots">
<template v-for="item in slots" :key="item" v-slot:[item]>
<slot :name="item"></slot>
</template>
<A-comp>
// 组件C-父组件
<div>
<B-comp :slots="slots">
<template v-for="(item, index) in slots" :key="item" v-slot:[item]>
{{index}}-{{item}}
</template>
</B-comp>
<div>
//script
const slots = ref(['name', 'number', 'id'])