v-if 和 v-show 的区别是什么?
Vue.js 中的 v-if 和 v-show 都是用来控制元素显示和隐藏的指令,但它们的工作原理、性能特性和使用场景有很大的不同。
以下是详细的对比总结:
1. 核心原理 (Implementation)
v-if (真正的条件渲染):
- 它是动态的。当条件为
true时,Vue 会将元素渲染并插入到 DOM 中;当条件为false时,Vue 会将元素从 DOM 中完全移除(销毁)。 - 它是惰性的。如果在初始渲染时条件为假,Vue 什么都不做——直到条件第一次变为真时,才会开始渲染条件块。
- 它是动态的。当条件为
v-show (CSS 切换):
- 无论初始条件是什么,元素始终会被渲染并保留在 DOM 中。
- 它只是简单地切换元素的 CSS 属性
display。- 条件为
true->display: block(或其他原值) - 条件为
false->display: none
- 条件为
2. 性能消耗 (Performance)
v-if:
- 初始渲染开销低:如果初始条件为
false,则不渲染。 - 切换开销高:每次切换时,都需要销毁和重建 DOM 元素(以及其内部的组件和事件监听器)。
- 初始渲染开销低:如果初始条件为
v-show:
- 初始渲染开销高:无论是否显示,都会渲染 DOM。
- 切换开销低:切换时只需修改 CSS 属性,不涉及 DOM 结构的增删。
3. 生命周期 (Lifecycle)
v-if:
- 切换时会触发组件的生命周期钩子。
- 显示时触发:
beforeCreate,created,beforeMount,mounted。 - 隐藏时触发:
beforeDestroy,destroyed(Vue 3 中为beforeUnmount,unmounted)。
v-show:
- 切换时不会触发组件的生命周期钩子(因为组件一直存在)。
- 组件仅在页面初始化加载时触发一次
mounted等钩子。
4. 语法支持
v-if:
- 支持
v-else和v-else-if。 - 支持在
<template>标签上使用(用于分组渲染多个元素)。
- 支持
v-show:
- 不支持
v-else。 - 不支持
<template>标签。
- 不支持
总结与使用场景建议
| 特性 | v-if | v-show |
|---|---|---|
| DOM 表现 | 销毁/重建 DOM 节点 | 修改 display: none |
| 初始渲染成本 | 低 (惰性) | 高 (总是渲染) |
| 切换成本 | 高 | 低 |
| 生命周期 | 切换时触发销毁/挂载 | 仅初始化触发,切换不触发 |
| template 支持 | 支持 | 不支持 |
什么时候用哪个?
使用
v-show:- 如果元素需要非常频繁地切换(例如:Tab 切换、下拉菜单、折叠面板、由 hover 触发的显示隐藏)。
- 因为此时重绘 DOM 的代价太高,用 CSS 切换更流畅。
使用
v-if:- 如果在运行时条件很少改变,或者一次性渲染。
- 如果条件为假时,该部分包含大量数据或复杂组件,为了加快首屏加载速度(利用其惰性)。
- 当需要与
v-else配合使用时。
右滑查看面试常问