Q12
★ ★ ★ ★ ★
Vue 3 是如何实现条件渲染的?
⚡ 速记答案(30 秒)
编译阶段:把 v-if/v-else-if/v-else 转为 render 函数中的条件表达式。运行阶段:依赖变化 → 重新执行 render → 生成对应分支的 VNode。
📖 详细讲解
标准面试回答(推荐记住)
编译时,v-if 等指令会被转换为 render 函数中的三元表达式或条件语句。运行时,当条件相关的响应式数据变化,会重新执行 render 函数生成新的 VNode 树,diff 阶段只对变化的分支打补丁。
v-if vs v-show 实现原理
v-if (真正的条件渲染):
- 编译后:三元表达式
flag ? h('div') : createCommentVNode()。 - 行为:当条件为 false 时,DOM 元素被完全销毁(或不创建)。切换时触发完整的组件销毁/挂载生命周期。
- 懒加载:初始 false 时什么都不做。
v-show (CSS 切换):
- 编译后:
withDirectives(h('div'), [[vShow, flag]])。 - 行为:元素始终被渲染并保留在 DOM 中,只是切换 CSS
display: none。 - 开销:初始渲染开销大,切换开销极小。
源码层面的 Block 优化
Vue 3 的 Block Tree 机制会记录 v-if 的分支结构 (Structure Directive),确保 diff 时结构稳定,不会因为分支切换导致 PatchFlag 混乱。
✅ 面试要点
- •理解 v-if 和 v-show 的区别
- •知道编译时的转换规则
- •了解 diff 时的优化策略
💻 代码示例
条件渲染编译结果
// 模板
// <div v-if="show">A</div>
// <div v-else>B</div>
// 编译后
function render(_ctx) {
return _ctx.show
? h('div', null, 'A')
: h('div', null, 'B')
}
// v-show 则是控制 display 样式
// <div v-show="visible">Content</div>
// 编译后
function render(_ctx) {
return h('div', {
style: { display: _ctx.visible ? null : 'none' }
}, 'Content')
}