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

相关推荐
安全系统学习4 分钟前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
涛哥码咖20 分钟前
chrome安装AXURE插件后无效
前端·chrome·axure
OEC小胖胖31 分钟前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水1 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
Sally璐璐1 小时前
零基础学HTML和CSS:网页设计入门
前端·css
老虎06271 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
三水气象台1 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
灿灿121381 小时前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css
烛阴2 小时前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript
AntBlack2 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python