一、概念
在 Vue 中,v-show
与 v-if
都能控制元素在页面上的显示与隐藏。
它们在语法层面几乎一致:
ini
<Model v-show="isShow" />
<Model v-if="isShow" />
当表达式为 true
时,元素可见;为 false
时,元素不可见。
表面上效果相同,但它们在实现原理、性能消耗、触发生命周期等方面却有显著差异。
二、共同点
- 作用效果相同:都能控制元素是否显示在页面中。
- 语法用法相同:都接收一个布尔值或表达式。
三、区别解析
1. 控制手段不同
- v-show :通过设置
display: none
隐藏元素,DOM 节点依旧存在。 - v-if :根据条件真正地 创建或销毁 DOM 节点。
2. 编译过程不同
- v-show:只做样式切换,逻辑简单,不涉及编译卸载。
- v-if:有完整的编译/卸载过程,会销毁和重建子组件与事件监听。
3. 生命周期触发
- v-show :切换时 不会触发生命周期钩子。
- v-if :从
false → true
会触发beforeCreate → created → beforeMount → mounted
;
从true → false
会触发beforeDestroy → destroyed
。
4. 性能消耗
- v-show:初始渲染开销大(始终渲染),切换开销小(仅改 CSS)。
- v-if:初始渲染开销小(按条件渲染),切换开销大(频繁销毁/重建 DOM)。
四、底层原理
v-show 原理
源码位置:runtime-dom/src/directives/vShow.ts
简化逻辑如下:
javascript
export const vShow = {
beforeMount(el, { value }) {
// 保存原始 display 值
el._vod = el.style.display === 'none' ? '' : el.style.display
setDisplay(el, value) // 根据表达式控制 display
},
updated(el, { value }) {
setDisplay(el, value)
}
}
👉 总结:无论条件真假,元素始终渲染,只是通过 display
控制显示与否。
v-if 原理
源码位置:compiler-core/src/transforms/vIf.ts
简化逻辑如下:
javascript
export const transformIf = createStructuralDirectiveTransform(
/^(if|else|else-if)$/,
(node, dir, context) => {
return processIf(node, dir, context, (ifNode, branch, isRoot) => {
return () => {
if (isRoot) {
ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context)
} else {
// else/else-if 附加到 v-if 根节点
const parentCondition = getParentCondition(ifNode.codegenNode!)
parentCondition.alternate = createCodegenNodeForBranch(branch, key, context)
}
}
})
}
)
👉 总结:通过 AST 转换生成不同的分支节点,真正决定是否生成 DOM。
五、使用场景
-
适合用 v-show:
- 需要频繁切换的场景(如 Tab 页切换、折叠面板)。
-
适合用 v-if:
- 条件很少变化的场景(如按权限渲染按钮、初始化渲染大块组件)。
六、对比总结表
特性 | v-show | v-if |
---|---|---|
控制手段 | CSS display:none |
DOM 节点增删 |
编译过程 | 简单,无编译卸载 | 有编译/卸载,重建子组件 |
生命周期触发 | 不触发 | 会触发创建/销毁钩子 |
性能特点 | 初始渲染耗时,切换高效 | 初始快,频繁切换性能差 |
适用场景 | 高频切换 | 条件偶尔变化 |
七、记忆口诀
"常切换用 v-show,偶尔显示用 v-if"
------一句话总结性能差异与使用场景。
八、拓展思考
-
过渡动画:
v-if
可结合<transition>
在 DOM 创建/销毁时触发进出动画。v-show
只会控制display
,动画需结合 CSStransition
实现。
-
SSR(服务端渲染)差异:
v-if
在服务端能减少不必要的 DOM 节点输出。v-show
SSR 输出时仍会包含该节点,只是隐藏。
-
组合使用 :
有时可结合使用,比如外层用
v-if
控制大范围渲染,内层用v-show
控制局部切换。
九、潜在问题
- 误用 v-show:可能导致页面存在过多隐藏 DOM,影响内存占用。
- 误用 v-if:在高频切换场景下导致性能瓶颈(频繁重建 DOM)。
- 误解生命周期:开发者常误以为 v-show 也会触发生命周期,实际并不会。
十、结语
v-show
与 v-if
虽然看似类似,但本质上是 "样式切换" vs "结构渲染" 的区别。合理选择它们能让项目性能与体验更优。
👉 记住一句话:
"频繁切换用 v-show,条件变化用 v-if"。
本文部分内容借助 AI 辅助生成,并由作者整理审核。