vue3的插槽slots和vue2有何不同

100 阅读1分钟

vue3的插槽slots和vue2有何不同

Vue 3 的插槽(Slots)机制在整体逻辑上与 Vue 2 保持一致,但在实现细节、性能优化和语法上有一些重要改进。以下是 Vue 3 和 Vue 2 插槽的主要区别:

1. 作用域插槽的语法统一

Vue 2

  • 作用域插槽:使用 slot-scope 属性,或 v-slot(仅在 Vue 2.6+ 支持)。
<!-- 父组件 -->
<template slot-scope="props">
  <div>{{ props.data }}</div>
</template>

Vue 3

  • 统一使用 v-slot:语法更简洁,且支持缩写 #
<!-- 父组件 -->
<template v-slot:default="props">
  <div>{{ props.data }}</div>
</template>
<!-- 缩写 -->
<template #default="props">
  <div>{{ props.data }}</div>
</template>

2. this.$slots 的变化

Vue 2

  • 普通插槽:通过 this.$slots 直接访问静态插槽内容。

  • 作用域插槽:通过 this.$scopedSlots 访问函数式插槽。

// Vue 2
this.$slots.default;       // 普通插槽内容
this.$scopedSlots.default; // 作用域插槽函数

Vue 3

  • 统一为函数:所有插槽都通过 this.$slots 访问,且每个插槽是一个函数。
// Vue 3
this.$slots.default();     // 返回普通插槽的虚拟节点数组

3. 性能优化:静态提升

Vue 2

  • 无静态提升:父组件每次渲染时,子组件的插槽内容会重新生成。

Vue 3

  • 静态提升(Static Hoisting):静态插槽内容会被提升到父组件之外,避免重复渲染。
<!-- 父组件 -->
<ChildComponent>
  <div>静态内容</div> <!-- 会被提升,避免重复渲染 -->
</ChildComponent>

4. 更灵活的动态插槽

Vue 3

  • 动态插槽名:支持通过动态指令参数绑定插槽名。
<template #[dynamicSlotName]="props">
  <div>{{ props.data }}</div>
</template>

5. 移除 slotslot-scope 属性

Vue 2

  • 支持 slot 属性定义具名插槽:
<!-- 子组件 -->
<slot name="header"></slot>

<!-- 父组件 -->
<div slot="header">Header</div>

Vue 3

  • 废弃 slot 属性:统一使用 v-slot 指令。
<!-- 父组件 -->
<template #header>
  <div>Header</div>
</template>

6. 更清晰的编译输出

Vue 3 的编译器会生成更高效的虚拟 DOM 代码:

  • 扁平化插槽内容:减少嵌套层级。

  • 优化作用域插槽:将其编译为函数,延迟渲染。

7. 示例对比

Vue 2

<!-- 子组件 -->
<slot name="item" :item="itemData"></slot>

<!-- 父组件 -->
<template slot="item" slot-scope="props">
 <div>{{ props.item }}</div>
</template>

Vue 3

<!-- 子组件 -->
<slot name="item" :item="itemData"></slot>

<!-- 父组件 -->
<template #item="props">
  <div>{{ props.item }}</div>
</template>

总结

Vue 3 的插槽机制在以下方面优化:

  1. 语法统一:使用 v-slot 替代 slot-scopeslot

  2. 性能提升:静态提升、扁平化插槽内容。

  3. API 简化this.$slots 统一为函数式访问。

  4. 动态插槽支持:通过 #[dynamicSlotName] 实现动态插槽名。

这些改进使得插槽的使用更高效、简洁,同时保持了向下兼容性(Vue 3 仍支持部分 Vue 2 语法,但推荐使用新语法)。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github