Vue 插槽 (Slots) 原理
1. 面试题
Q: 默认插槽、具名插槽、作用域插槽有什么区别?Vue 3 对插槽做了什么优化?
2. 三种插槽
(1) 默认插槽 (Default)
父组件的内容直接分发到子组件的 <slot /> 位置。
(2) 具名插槽 (Named)
当子组件有多个分发点(Header, Main, Footer)时使用。
- 用法:
<template #header>...</template> (v-slot 缩写为 #)。
(3) 作用域插槽 (Scoped)
核心作用:数据反向传递。让父组件在渲染插槽内容时,能访问到子组件的数据。
- 子组件:
<slot :item="item" />
- 父组件:
<template #default="{ item }">{{ item.name }}</template>
3. 实现原理与优化
(1) Vue 2 实现
- 普通插槽:在父组件编译阶段直接生成 VNodes,传给子组件。缺点:父组件更新,子组件也被迫更新。
- 作用域插槽:编译成函数,子组件渲染时调用。
(2) Vue 3 优化 (All Slots are Functions)
- 统一:Vue 3 将所有插槽(包括默认和具名)都编译为函数。
- 延迟渲染:只有当子组件渲染该 slot 时,才执行函数生成 VNodes。
- 收益:
- 父组件更新,只重新渲染父组件。
- 子组件插槽内容变化,只触发子组件更新。
- 实现了父子更新隔离,性能大幅提升。