在 Vue 开发中,v-if 和 v-show 都可以用来控制元素或组件的显示与隐藏,但它们的实现方式、性能特征、适用场景完全不同 。
如果用错,轻则代码臃肿,重则性能下降、状态丢失。
这篇文章不讲概念堆砌,只讲工程上该怎么选。
一、最核心的区别
-
v-if :条件不满足时,DOM / 组件 根本不存在
-
v-show :条件不满足时,DOM / 组件 仍然存在,只是
display: none
这一个区别,决定了后面所有行为。
二、渲染机制差异
v-if 的行为
-
条件为
false:不渲染、不创建组件 -
条件为
true:创建 DOM / 组件实例 -
条件反复切换:反复创建 + 销毁
javascript
<MyComponent v-if="visible" />
本质是「条件渲染」
v-show 的行为
-
无论条件真假:都会先渲染一次
-
条件切换时:只修改
display样式
javascript
<MyComponent v-show="visible" />
本质是「样式控制」
三、性能对比(重点)
1️⃣ 首次渲染性能
-
v-if 更好
-
初始为
false时,完全不创建 DOM -
首屏更轻
-
-
v-show 较差
-
即使初始不显示,也会渲染
-
所有组件都会走一遍
mounted
-
结论:
首屏性能敏感、默认不展示 → v-if 更好
2️⃣ 切换性能
-
v-if 较差
-
每次切换都涉及:
-
创建 / 销毁 DOM
-
组件生命周期重新执行
-
-
-
v-show 更好
-
只改 CSS
-
几乎是 O(1) 操作
-
结论:
高频切换 → v-show 完胜
状态保留(工程中最容易踩坑)
-
v-if
-
组件被销毁
-
所有内部状态都会丢失:
-
表单输入
-
滑块位置
-
滚动位置
-
内部 ref / reactive 状态
-
-
-
v-show
-
组件始终存在
-
状态完整保留
-
结论:
需要保留状态 → 只能用 v-show
四、生命周期差异
v-if
javascript
false → true : onMounted
true → false : onUnmounted
v-show
javascript
只在首次渲染时 onMounted
之后切换不触发生命周期
五、动画能力
-
v-if
-
适合"进出场动画"
-
和
<transition>配合自然
-
-
v-show
-
也能动画,但本质是 display 切换
-
更适合透明度、高度类动画
-
六、谁性能更好?
没有绝对更好的,只有"更适合当前场景的"
| 场景 | 推荐 |
|---|---|
| 首屏不显示 | v-if |
| 高频切换 | v-show |
| 保留状态 | v-show |
| 重组件(列表/图表) | v-if |
| Tab 切换 | v-show |
| 弹窗 / 抽屉 | v-if |
| 权限控制 | v-if |
七、工程级决策口诀(建议记住)
默认不用想,先用 v-show
只有当"默认不展示 + 首屏要轻"时,再换 v-if
这是一个安全默认值。
八、进阶:v-show 的唯一缺点 & 对策
问题
v-show 会让所有面板在首屏都渲染一次,如果某个面板非常重(比如长列表、复杂计算),会拖慢首屏。
解决方案(懒加载 v-show)
-
第一次点击才渲染
-
之后用 v-show 保留状态
这是工程中非常常见的折中方案。
九、真实项目中的典型选择
以「字体设置 Tab」为例:
-
用户会频繁来回切
-
每个面板有滑块、选择器、状态
-
不希望切一次丢一次状态
v-show 是唯一合理选择

总结
-
v-if是"是否存在" -
v-show是"是否可见" -
性能不是绝对,而是时间维度不同
-
首屏 → v-if
-
交互 → v-show
-