Vue 中 v-if 和 v-show 的区别、性能对比与使用场景(工程实战向)

在 Vue 开发中,v-ifv-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

相关推荐
随风一样自由6 小时前
【前端独角兽】刚进入前端领域的前端开发用jQuery还是Vue3?
前端·javascript·vue3·jquery
IMPYLH6 小时前
HTML 的 <data> 元素
前端·html
YHHLAI7 小时前
[特殊字符] 面试中的 Promise —— 从入门到精通
前端·javascript·面试
weixin_BYSJ19877 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
沪飘大军8 小时前
ll-llm:一个零依赖、可插拔的 OpenAI 兼容 LLM 代理
javascript
leoZ2318 小时前
Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践
vue.js·spring boot·架构
kyriewen9 小时前
我扒了 GPT-5.6 的全部编程跑分——有一项 OpenAI 没敢放出来
前端·gpt·ai编程
前端H9 小时前
微前端 v3 架构升级:从加载隔离到状态协同
前端·架构·状态模式
山河木马9 小时前
GPU自动处理专题3-NDC怎么映射成屏幕像素坐标(视口变换)
javascript·webgl·图形学
陆枫Larry10 小时前
小程序包体积优化:用 SVG 图片替换 iconfont,并保留 CSS 控色能力
前端