Vue-slot插槽

113 阅读2分钟

1. slot 插槽的概念

插槽相当于一个占位符,可以把父组件里的内容渲染到子组件里面

image.png

2. slot 插槽的分类

  • 具名插槽: 给插槽取个名字,一个萝卜一个坑,子组件中slot标签通过name属性给插槽命名, 在父组件通过 #namev-slot:namev-slot="name"来决定渲染到哪个slot标签中

image.png

  • 可传参插槽:slot标签,除了name属性是被占用的,传入的其他属性可以作为变量传递给使用插槽的地方,父组件可以使用#name="scope"v-slot:name="scope"来接受,scope就是传递过来的参数,是一个Object对象,key名就是slot标签的属性名

image.png

  • 动态具名插槽:插槽的名字可以使用变量。slot标签中使用:name="xxx"来取名,父组件中使用#[xxx]v-slot:[xxx]

image.png

子组件中获取所有父组件传过来的插槽

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'])