一、基础区别
| 特性 | v-if | v-show |
|---|---|---|
| 渲染机制 | 条件为假时,完全移除 DOM 元素 | 条件为假时,隐藏 DOM 元素(display: none) |
| 编译过程 | 惰性渲染:条件首次为真时才渲染 | 初始渲染时就创建元素 |
| 性能消耗 | 切换时有较高开销(涉及 DOM 增删) | 切换时开销较低(仅修改 CSS 属性) |
| 适用场景 | 运行时条件很少改变的场景 | 需要频繁切换显示状态的场景 |
二、代码示例对比
<!-- v-if 示例 -->
<div v-if="isLoggedIn">欢迎回来!</div>
<!-- v-show 示例 -->
<div v-show="isLoading">加载中...</div>
三、执行流程差异
-
v-if 的执行流程
- 条件为
false时:DOM 中不存在该元素。 - 条件变为
true时:动态创建元素,并触发组件生命周期钩子(如mounted)。
- 条件为
-
v-show 的执行流程
- 无论条件真假,元素始终存在于 DOM 中。
- 通过修改
display样式控制显示/隐藏,不触发生命周期钩子。
四、性能考量
-
频繁切换场景:使用
v-show,避免重复创建和销毁 DOM 元素。<!-- 频繁显示/隐藏的提示框 --> <div v-show="showTooltip">这是一个提示</div> -
条件很少改变场景:使用
v-if,初始渲染时可减少 DOM 节点数量。<!-- 用户登录状态,很少切换 --> <div v-if="user.isAdmin">管理员面板</div>
五、特殊场景注意事项
1. 与 v-for 同时使用
- 不推荐:
v-if优先级高于v-for,可能导致意外行为。 - 推荐方案:通过计算属性过滤列表数据。
<!-- 错误示例:可能导致遍历未定义数据 -->
<li v-for="item in list" v-if="item.visible">{{ item.name }}</li>
<!-- 正确示例:使用计算属性 -->
<li v-for="item in visibleList">{{ item.name }}</li>
<script>
export default {
computed: {
visibleList() {
return this.list.filter(item => item.visible);
}
}
}
</script>
2. 模板编译优化
v-if条件为false时,其内部的事件监听器和子组件不会被初始化。v-show无论条件如何,元素及其子元素都会被初始化。
六、问题
1. 问:何时该用 v-if,何时该用 v-show?
- 答:
- 若需要频繁切换显示状态(如表单验证提示),使用
v-show。 - 若条件在运行时很少改变(如权限控制),使用
v-if以减少初始 DOM 体积。
- 若需要频繁切换显示状态(如表单验证提示),使用
2. 问:v-if 和 v-show 对组件生命周期有何影响?
- 答:
v-if切换时会触发组件的挂载(mounted)和销毁(destroyed)钩子。v-show切换时不会触发任何生命周期钩子。
3. 问:v-if 和 v-show 哪个性能更好?
- 答:
- 初始渲染:
v-if在条件为false时更优(不渲染元素)。 - 频繁切换:
v-show更优(仅修改 CSS,无 DOM 操作)。
- 初始渲染: