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

相关推荐
ohyeah3 分钟前
深入理解 React Hooks:useState 与 useEffect 的核心原理与最佳实践
前端·react.js
Cache技术分享4 分钟前
275. Java Stream API - flatMap 操作:展开一对多的关系,拉平你的流!
前端·后端
yaoh.wang5 分钟前
力扣(LeetCode) 100: 相同的树 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
apollo_qwe28 分钟前
前端缓存深度解析:从基础到进阶的实现方式与实践指南
前端
学习CS的小白35 分钟前
跨域问题详解
vue.js·后端
周星星日记36 分钟前
vue中hash模式和history模式的区别
前端·面试
Light6036 分钟前
Vue 高阶优化术:v-bind 与 v-on 的实战妙用与思维跃迁
前端·低代码·vue3·v-bind·组件封装·v-on·ai辅助开发
周星星日记36 分钟前
5.为什么vue中使用query可以保留参数
前端·vue.js
lebornjose37 分钟前
javascript - webgl中绑定(bind)缓冲区的逻辑是什么?
前端·webgl
小丑75539 分钟前
Vue 转盘抽奖 transform
面试