

今天给大家聊聊vue 中v-show和v-if 之间的区别以及如何选择,希望对前端入门的朋友提供实用的参考!
v-show 的工作非常简单粗暴:不管条件成不成立,它都会把这个元素真实地渲染到DOM树中。当条件为 false 时,它只是简单地给这个元素加上了一个 style="display: none;" 的内联样式,把它隐藏起来。

它的工作流程:
数据变化 → 计算条件 → 切换CSS的display属性
真实案例:一个高频切换的Tab栏
想象一个产品详情页,有“商品详情”、“规格参数”、“售后保障”三个Tab。用户会频繁地点击切换。
<template>
<div>
<button @click="currentTab = 'detail'">商品详情</button>
<button @click="currentTab = 'spec'">规格参数</button>
<button @click="currentTab = 'service'">售后保障</button>
<div v-show="currentTab === 'detail'">
<h3>这里是巨长的商品图文详情...</h3>
<p>很多图片和文字...</p>
</div>
<div v-show="currentTab === 'spec'">
<h3>规格参数表</h3>
<table>...</table>
</div>
<div v-show="currentTab === 'service'">
<h3>售后政策</h3>
<p>七天无理由退换货...</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
currentTab: 'detail'
}
}
}
</script>适用场景
因为用户会频繁点击切换,这三个Tab的内容从一开始就已经被渲染好了。使用 v-show 只是在显示和隐藏之间切换,代价极小(仅仅是修改CSS),非常流畅。如果用 v-if,每次切换都要重新创建或销毁整个DOM结构,开销更大,可能会感到卡顿。
v-if是真正意义上的条件渲染。当条件为 true 时,它会把这个元素构建(渲染)到DOM树中;当条件为 false 时,它会直接把这个元素从DOM树中彻底拆除(销毁),连带着它内部的所有事件监听器和子组件都会被销毁和重建。

它的工作流程:
数据变化 → 计算条件 → true:创建并插入DOM / false:销毁并移除DOM
真实案例:一个需要权限控制的“管理按钮”
假设有一个页面,普通用户看不到“删除”按钮,只有管理员登录后才看到。
<template>
<div>
<h1>文章列表</h1>
<ul>...</ul>
<!-- 这个按钮不是一直需要的,只有在管理员身份时才出现 -->
<button v-if="user.role === 'admin'" @click="deleteArticle">
删除文章
</button>
</div>
</template>
<script>
export default {
data() {
return {
user: {
role: 'user' // 默认是普通用户
}
}
},
methods: {
deleteArticle() { ... }
}
}
</script>安全性考虑:对于这种权限相关的元素,直接不渲染比隐藏起来更安全。虽然CSS可以隐藏,但在浏览器开发者工具里还是能看到这个按钮的DOM结构,一些懂行的用户可能会直接去掉display: none样式来操作,存在风险。
性能考虑:绝大多数用户都不是管理员,这个按钮根本就不会出现。因此,在绝大多数情况下,根本不需要渲染这个按钮相关的DOM节点和事件监听,节省了初始渲染的性能。如果用 v-show,这个按钮的DOM结构无论如何都会存在,只是被隐藏了,是一种浪费。
特性 | v-show | v-if |
|---|---|---|
工作原理 | 控制CSS的display属性 | 动态添加/移除DOM元素 |
初始渲染成本 | 高,无论条件是否成立,初始都会渲染 | 低,条件为false时完全不渲染 |
切换开销 | 低,仅仅是修改CSS | 高,涉及组件的销毁和重建 |
适用场景 | 频繁切换的场景(如Tab、折叠面板) | 运行时条件很少改变,或者条件为false时不需要渲染的场景(如权限控制、初始不需要渲染的弹窗) |
“惰性”渲染 | 不惰性,总是会渲染 | 惰性,初始为false时什么都不做,直到条件变为true |
v-if 还可以搭配 v-else-if 和 v-else 使用,实现典型的“如果...否则如果...否则”的逻辑,就像JavaScript中的 if...else 语句一样,非常强大和直观。而 v-show 没有这样的语法。
<p v-if="score >= 90">优秀</p>
<p v-else-if="score >= 60">及格</p>
<p v-else>不及格</p>先问频率:“这个元素需要非常非常频繁地显示和隐藏吗?”
是 -> 毫不犹豫,用 v-show。
否 -> 进入下一个问题。
再问必要性:“在绝大多数情况下,或者页面刚加载时,这个元素需要被渲染出来吗?”
不需要,或者权限/条件可能不满足 -> 用 v-if(比如权限按钮、按需弹出的模态框)。
需要 -> 进入下一个问题。
最后问复杂度:“这个元素或者它包含的组件,内部结构复杂吗?初始化成本高吗?”
非常复杂(比如里面有很多数据、图表、子组件) -> 考虑用 v-if,避免初始渲染不必要的复杂组件以提升页面加载性能。
不复杂 -> 两者都可以,但如果切换频率不高,用 v-if 更省长期内存。
简单总结一下选择思路:频繁切换,用show;条件不变,用if。
v-show 和 v-if 是Vue给我们的两把好用的“开关”,没有绝对的谁好谁坏,只有合不合适的场景。
v-show 通过CSS玩“隐身”,开销在初始渲染,切换时性能更好。适合需要“高频切换”的场合。
v-if 通过操作DOM玩“真假美猴王”,开销在切换过程,初始渲染可能更高效。适合“一次性决定显示隐藏”或者“条件很少改变”的场合。
希望这篇文章能帮大家理清思路。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。