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

相关推荐
并不会36 分钟前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、39 分钟前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜39 分钟前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师42 分钟前
CSS的三个重点
前端·css
耶啵奶膘2 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^4 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie4 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic5 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿5 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具5 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端