深入vue2/3: 插槽 <slot> / v-slot 的使用与讲解
默认插槽,具名插槽,作用域插槽首先简单阐述下基础定义和基础使用,再深入讲解各个使用方法、细节、效果:子组件声明<slot></slot>,然后父组件使用子组件时,传入对应的 slot 内容。也就是子组件使用<slot>插槽标签,父组件使用v-slot指令,需要两者结合使用,若父组件没声明v-slot内容,子组件slot对应位置则无内容。当子组件slot内声明有默认内容时,那父组件不声明v-slot
首先简单阐述下 基础定义和基础使用 ,再深入讲解各个使用方法、细节、效果:
- 子组件声明<slot></slot>,然后父组件使用子组件时,传入对应的 slot 内容。也就是子组件使用<slot>插槽标签,父组件使用v-slot指令,需要两者结合使用,若父组件没声明v-slot内容,子组件slot对应位置则无内容。
- 当子组件slot内声明有默认内容时,那父组件不声明v-slot,子组件则会使用默认内容,例如:<slot>默认值</slot>
- 插槽可以包含任何内容,例如:模板代码、 HTML、组件、普通文本。
v-slot 详解 (父组件定义的)
-
缩写:
#
-
使用条件:
template
标签,<template #default></template> (默认插槽可不需要template)
- 子组件 (对于一个单独的带 prop 的默认插槽。用人话讲就是子组件里要有<slot>)
<slot> 详解 (子组件定义的)
-
参数:
-
插槽名 (可选,默认值是 default)
-
<slot></slot>
不声明,默认name
是default
<slot name="JuMingSlot"></slot>
- 其他 prop,如
slotData ,这种属于作用域插槽,见下面案例讲解。
<slot name="JuMingSlot" :slotData='data'></slot>
为作用域插槽
-
-
插槽类型:
<slot></slot>
为默认插槽<slot name="JuMingSlot"></slot>
为具名插槽<slot name="JuMingSlot" :slotData='data'></slot>
为作用域插槽
插槽类型:1 和 2
// 父组件 <template> <childComponent> <!-- 默认传入的就是`default`,所以可以省略`template`来包裹 --> <span>默认插槽:{{ customEventData }}</span> <template #JuMingSlot> <!-- #JuMingSlot 等同于 v-slot:JuMingSlot --> <span style="background-color:#41B883;color:white;">具名插槽 与 $slots</span> </template> </childComponent> </template>
父组件此时用了默认插槽和具名插槽,但是默认插槽没有用template的包裹!虽然有效,但是按照官方建议,这是不太规范的!
// 子组件 childComponent <template> <div>啊,这光,这水,充满经费的气息</div> <slot></slot> <slot name="JuMingSlot"></slot> </template>
默认值:当 slot 内写了内容时,如果父组件不提供 slot 内容,则会使用子组件 slot 的默认内容
如果子组件没有slot
,父组件声明使用了,那声明的传入的内容会被丢弃// childComponent <template> <slot>啊,这光,这水,充满经费的气息</slot> </template>
插槽类型:3. 作用域插槽
功能:父组件使用子组件内的数据,父组件得到的是个对象,对象里的数据就是子组件声明slot对应父组件可用的内容
注意!父组件#name="{}" 此处是js的解构,也就是说这获得的是一个对象,对象里面包含子组件插槽传给父组件的数据。对象内的key 就是插槽 prop 的name。
// 父组件 <template> <!-- 接收 prop 的插槽 --> <childComponent> <template #default='{defaultData}'> <span>{{defaultData}}</span> </template> <template #JuMingSlot='{slotData}'> <span>{{slotData}}</span> </template> <template #propDatas='{data1,data2}'> <span>{{data1}}{{data2}}</span> </template> </childComponent> </template>
// 子组件 childComponent <template> <div>啊,这光,这水,充满经费的气息</div> <slot :defaultData='defaultData'></slot> <slot name="JuMingSlot" :slotData='childData'></slot> <slot name="propDatas" :data1='childData' :data2='defaultData'></slot> </template> <script> export default { data(){ return{ childData:'吹响吧,上低音号', defaultData:'默认插槽的数据', } } } </script>
规范
1、只要出现多个插槽,请始终为所有的 插槽使用完整的基于 <template>
的语法:
<todo-list>
<template v-slot:default="slotProps">
<i class="fas fa-check"></i>
<span class="green">{{ slotProps.item }}</span>
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</todo-list>
2、默认插槽的 v-slot 缩写配合作用域插槽时:<template #='{propData}'>,这个写法虽然有效,但不建议! 原因:官方说这写法是无效的,并会抛出一个警告。但实际有效,警告也没见到。。
但为了统一规范并且预防后续vue3迭代升级真的就变无效了。。
统一写为:<template #default='{propData}'>
// 父组件
<template>
<childComponent>
<template #default='{defaultData}'>
<span>{{defaultData}}</span>
</template>
</childComponent>
</template>
更多推荐
所有评论(0)