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. 移除 slot 和 slot-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 的插槽机制在以下方面优化:
-
语法统一:使用
v-slot替代slot-scope和slot。 -
性能提升:静态提升、扁平化插槽内容。
-
API 简化:
this.$slots统一为函数式访问。 -
动态插槽支持:通过
#[dynamicSlotName]实现动态插槽名。
这些改进使得插槽的使用更高效、简洁,同时保持了向下兼容性(Vue 3 仍支持部分 Vue 2 语法,但推荐使用新语法)。
更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github