深入vue2/3: 插槽 <slot> / v-slot 的使用与讲解

44 篇文章 6 订阅

首先简单阐述下 基础定义和基础使用 ,再深入讲解各个使用方法、细节、效果:

  • 子组件声明<slot></slot>,然后父组件使用子组件时,传入对应的 slot 内容。也就是子组件使用<slot>插槽标签,父组件使用v-slot指令,需要两者结合使用,若父组件没声明v-slot内容,子组件slot对应位置则无内容。
  • 当子组件slot内声明有默认内容时,那父组件不声明v-slot,子组件则会使用默认内容,例如:<slot>默认值</slot>
  • 插槽可以包含任何内容,例如:模板代码、 HTML、组件、普通文本。

v-slot 详解 (父组件定义的)

  • 缩写:#

  • 使用条件:

    1. template标签,<template #default></template> (默认插槽可不需要template)
    2. 子组件 (对于一个单独的带 prop 的默认插槽。用人话讲就是子组件里要有<slot>)

<slot> 详解 (子组件定义的)

  • 参数:

    • 插槽名 (可选,默认值是 default)

    1. <slot></slot> 不声明,默认name是 default

    2. <slot name="JuMingSlot"></slot>
    • 其他 prop,如 slotData ,这种属于作用域插槽,见下面案例讲解。
    1. <slot name="JuMingSlot" :slotData='data'></slot> 为作用域插槽
  • 插槽类型:

    1. <slot></slot> 为默认插槽
    2. <slot name="JuMingSlot"></slot> 为具名插槽
    3. <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>

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值