(Vue)slot 是什么?有什么作用?原理是什么?

slot 又名插槽,是 Vue 的内容分发机制,组件内部的模板引擎使用slot 元素作为承载分发内容的出口。插槽 slot 是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。slot 又分三类,默认插槽,具名插槽和作用域插槽。

默认插槽(Default Slot):

  • 默认插槽是最简单的插槽类型,用于传递未命名的内容到子组件。
  • 在父组件中,可以通过在子组件的标签内放置内容来传递数据。
  • 一个组件内只有有一个匿名插槽。
html 复制代码
<!-- Parent Component -->
<template>
  <app-child>
    This content will be placed in the default slot.
  </app-child>
</template>
html 复制代码
<!-- Child Component -->
<template>
  <div>
    <slot></slot>
  </div>
</template>

具名插槽(Named Slot) :

  • 具名插槽允许在父组件中将内容传递到特定的插槽位置。
  • 在子组件中使用<slot>元素的name属性为插槽命名。
  • 一个组件可以出现多个具名插槽。
html 复制代码
<!-- Parent Component -->
<template>
  <app-child>
    <template v-slot:header>
      Content for the header slot.
    </template>
    <template v-slot:footer>
      Content for the footer slot.
    </template>
  </app-child>
</template>
html 复制代码
<!-- Child Component -->
<template>
  <div>
    <header>
      <slot name="header"></slot>
    </header>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

作用域插槽(Scoped Slot) :

  • 作用域插槽允许子组件向父组件传递数据,使父组件能够使用子组件的数据。
  • 在子组件中使用<slot>元素的name属性,并使用v-bind绑定传递的数据。
html 复制代码
<!-- Parent Component -->
<template>
  <app-child>
    <template v-slot:default="slotProps">
      {{ slotProps.message }}
    </template>
  </app-child>
</template>
html 复制代码
<!-- Child Component -->
<template>
  <div>
    <slot :message="childMessage"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      childMessage: 'This message is from the child component.'
    };
  }
}
</script>

实现原理

  1. 子组件实例化时获取父组件传入的 slot 内容

    • 当子组件被实例化时,Vue.js会执行组件的生命周期钩子函数,其中created是一个常用的钩子。在created钩子中,可以通过访问this.$slots属性来获取父组件传递的插槽内容。
    javascript 复制代码
    // 子组件
    created() {
      this.$slot = this.$slots;
    }

    这样,this.$slot中就包含了所有插槽的内容,包括默认插槽和具名插槽。

  2. 插槽内容存放在 vm.$slot 中

    • 默认插槽的内容可以通过this.$slot.default来获取,而具名插槽的内容可以通过this.$slot.xxx来获取,其中xxx是具体的插槽名称。
    javascript 复制代码
    // 子组件
    created() {
      this.$slot = this.$slots;
      this.defaultSlotContent = this.$slot.default;
      this.namedSlotContent = this.$slot.xxx; // Replace 'xxx' with the actual slot name
    }

    这样,你就能在子组件中访问到父组件传递过来的不同插槽的内容。

  3. 组件执行渲染函数时替换 slot 标签

    • 在子组件的渲染函数中,可以通过访问this.$slots来获取插槽的内容,并将其用于替换模板中的<slot>标签。
    javascript 复制代码
    // 子组件的渲染函数
    render(h) {
      return h('div', [
        // 使用 this.$slots.default 替换默认插槽
        h('div', this.$slots.default),
    
        // 使用 this.$slots.xxx 替换具名插槽
        h('div', this.$slots.xxx), // Replace 'xxx' with the actual slot name
      ]);
    }

    这样,当子组件渲染时,插槽的内容就会被动态地插入到相应的位置。

  4. 作用域插槽的实现

    • 作用域插槽是通过在渲染函数中使用this.$scopedSlots来实现的。作用域插槽的内容可以通过函数调用,并传递数据给父组件。
    javascript 复制代码
    // 子组件的渲染函数
    render(h) {
      return h('div', [
        // 使用作用域插槽,并传递数据给父组件
        this.$scopedSlots.default({ message: 'Hello from child!' }),
      ]);
    }

    在父组件中,可以通过具名插槽的方式接收这个数据。

    html 复制代码
    <!-- 父组件模板 -->
    <template>
      <app-child>
        <template v-slot:default="slotProps">
          {{ slotProps.message }}
        </template>
      </app-child>
    </template>

通过以上步骤,实现了一个简单的插槽系统,支持默认插槽、具名插槽和作用域插槽。这种实现方式是Vue.js插槽机制的基础,它通过渲染函数和组件实例之间的关系来实现插槽的内容分发和数据传递。

相关推荐
※DX3906※12 分钟前
Java排序算法--全面详解面试中涉及的排序
java·开发语言·数据结构·面试·排序算法
We་ct2 小时前
LeetCode 77. 组合:DFS回溯+剪枝,高效求解组合问题
开发语言·前端·算法·leetcode·typescript·深度优先·剪枝
KerwinChou_CN2 小时前
什么是流式输出,后端怎么生成,前端怎么渲染
前端
努力学算法的蒟蒻2 小时前
day105(3.6)——leetcode面试经典150
算法·leetcode·面试
爱上妖精的尾巴2 小时前
8-20 WPS JS宏 正则表达式-懒惰匹配
服务器·前端·javascript
网络点点滴2 小时前
组件通信props方式
前端·javascript·vue.js
野犬寒鸦2 小时前
TCP协议核心:TCP详细图解及TCP与UDP核心区别对比(附实战解析)
服务器·网络·数据库·后端·面试
二十雨辰2 小时前
[小结]-线上Bug监控
前端·bug
前端技术2 小时前
【鸿蒙实战】从零打造智能物联网家居控制系统:HarmonyOS Next分布式能力的完美诠释
java·前端·人工智能·分布式·物联网·前端框架·harmonyos
CHU7290352 小时前
指尖践行环保——旧衣服回收小程序前端功能玩法详解
前端·小程序