(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插槽机制的基础,它通过渲染函数和组件实例之间的关系来实现插槽的内容分发和数据传递。

相关推荐
小白学习日记42 分钟前
【复习】HTML常用标签<table>
前端·html
程序员大金1 小时前
基于SpringBoot+Vue+MySQL的装修公司管理系统
vue.js·spring boot·mysql
丁总学Java1 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
yanlele1 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
懒羊羊大王呀2 小时前
CSS——属性值计算
前端·css
睡觉然后上课2 小时前
c基础面试题
c语言·开发语言·c++·面试
DOKE2 小时前
VSCode终端:提升命令行使用体验
前端
xgq2 小时前
使用File System Access API 直接读写本地文件
前端·javascript·面试
用户3157476081352 小时前
前端之路-了解原型和原型链
前端
永远不打烊2 小时前
librtmp 原生API做直播推流
前端