v-if 和 v-show 的区别
一句话总结
- v-if:条件满足才创建,不满足就销毁(条件渲染)
- v-show:总是创建,只是用CSS切换显示隐藏(显示切换)
比喻理解
v-if 就像租房
有钱时 → 租房子(创建DOM)
没钱时 → 退租(销毁DOM)
再有钱 → 重新租房(重新创建DOM)
v-show 就像开灯关灯
开灯时 → 房间亮着(display: block)
关灯时 → 房间黑了(display: none)
房间一直在,只是看不见
详细对比
|
特性 |
v-if |
v-show |
|
DOM操作 |
条件为假时,元素从DOM移除 |
条件为假时,元素还在DOM,只是 display: none |
|
首次渲染 |
条件为假时,不渲染元素 |
条件为假时,会渲染元素,然后隐藏 |
|
切换开销 |
高(销毁/重建DOM) |
低(只是CSS切换) |
|
生命周期 |
切换时触发创建/销毁钩子 |
只触发挂载,不会销毁 |
|
性能 |
适合不频繁切换的场景 |
适合频繁切换的场景 |
|
初始渲染 |
如果初始不需要,可节省资源 |
无论是否需要,都会渲染 |
代码示例
<template>
<div>
<!-- v-if 示例 -->
<div v-if="showWithIf">
这个内容在showWithIf为true时创建,为false时销毁
</div>
<!-- v-show 示例 -->
<div v-show="showWithShow">
这个内容一直存在,showWithShow为false时只是隐藏
</div>
<!-- 切换按钮 -->
<button @click="toggle">切换显示</button>
</div>
</template>
<script>
export default {
data() {
return {
showWithIf: false,
showWithShow: false
}
},
methods: {
toggle() {
this.showWithIf = !this.showWithIf
this.showWithShow = !this.showWithShow
}
},
mounted() {
console.log('组件挂载')
},
// 在控制台观察
// 当showWithIf为true时,会创建元素
// 当showWithIf为false时,元素会从DOM移除
// showWithShow的元素一直在DOM中
}
</script>
实际场景提议
✅ 用 v-if
<!-- 场景1:初始不需要的内容 -->
<div v-if="user.isAdmin">
<!-- 管理员面板,大部分用户看不到 -->
<AdminPanel />
</div>
<!-- 场景2:不常切换的组件 -->
<div v-if="currentTab === 'settings'">
<!-- 设置页面,不常切换 -->
<SettingsPage />
</div>
<!-- 场景3:提高初始加载速度 -->
<template v-if="dataLoaded">
<!-- 数据加载完才显示 -->
<DataTable :data="data" />
</template>
✅ 用 v-show
<!-- 场景1:频繁切换的UI -->
<div v-show="showToolbar">
<!-- 工具栏,频繁显示/隐藏 -->
<Toolbar />
</div>
<!-- 场景2:标签页内容 -->
<div v-show="activeTab === 'home'">
<!-- 标签页内容,切换频繁 -->
<HomeContent />
</div>
<div v-show="activeTab === 'profile'">
<ProfileContent />
</div>
<!-- 场景3:需要保留状态的表单 -->
<form v-show="showForm">
<!-- 表单输入状态需要保留 -->
<input v-model="formData" />
</form>
性能对比演示
<template>
<div>
<h2>性能测试</h2>
<!-- 测试按钮 -->
<button @click="toggleMode">当前模式:{{ mode === 'v-if' ? 'v-if' : 'v-show' }}</button>
<button @click="startTest">开始测试(切换1000次)</button>
<!-- 测试结果 -->
<p>v-if 耗时:{{ ifTime }}ms</p>
<p>v-show 耗时:{{ showTime }}ms</p>
<!-- 测试区域 -->
<div v-if="mode === 'v-if'">
<div v-if="isVisible">v-if 内容</div>
</div>
<div v-else>
<div v-show="isVisible">v-show 内容</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
mode: 'v-if',
isVisible: true,
ifTime: 0,
showTime: 0
}
},
methods: {
toggleMode() {
this.mode = this.mode === 'v-if' ? 'v-show' : 'v-if'
},
startTest() {
if (this.mode === 'v-if') {
this.testVif()
} else {
this.testVshow()
}
},
testVif() {
const start = performance.now()
// 模拟快速切换1000次
for (let i = 0; i < 1000; i++) {
this.isVisible = !this.isVisible
// 需要强制更新
this.$forceUpdate()
}
this.ifTime = performance.now() - start
},
testVshow() {
const start = performance.now()
for (let i = 0; i < 1000; i++) {
this.isVisible = !this.isVisible
this.$forceUpdate()
}
this.showTime = performance.now() - start
}
}
}
</script>
结果:v-show 的切换速度一般比 v-if 快许多倍。
特殊注意事项
1. 与 <template>标签一起使用
<!-- v-if 可以与 <template> 一起使用 -->
<template v-if="condition">
<div>内容1</div>
<div>内容2</div>
</template>
<!-- v-show 不能与 <template> 一起使用 -->
<!-- ❌ 这是错误的 -->
<template v-show="condition">
<div>内容</div>
</template>
2. 与 v-else 配合
<!-- v-if 可以配合 v-else -->
<div v-if="isLoggedIn">欢迎回来!</div>
<div v-else>请先登录</div>
<!-- v-show 不能配合 v-else -->
<!-- ❌ 这是错误的 -->
<div v-show="isLoggedIn">欢迎回来!</div>
<div v-else>请先登录</div>
3. 对子组件的影响
<template>
<div>
<!-- 子组件会随 v-if 销毁/重建 -->
<ChildComponent v-if="showChild" />
<!-- 触发 created、mounted、beforeDestroy、destroyed -->
<!-- 子组件不会随 v-show 销毁 -->
<ChildComponent v-show="showChild" />
<!-- 只触发 created、mounted,不会销毁 -->
</div>
</template>
4. 对 <input>值的影响
<template>
<div>
<!-- v-if:切换时会丢失输入值 -->
<input v-if="showInput" v-model="inputValue" placeholder="v-if输入" />
<!-- v-show:切换时保留输入值 -->
<input v-show="showInput" v-model="inputValue" placeholder="v-show输入" />
<button @click="showInput = !showInput">切换显示</button>
</div>
</template>
记忆口诀
v-if 是懒汉,不用就不干
v-show 是勤快,干了藏起来
创建销毁用 v-if
显示隐藏用 v-show
选择指南
问自己:
1. 这个元素会频繁显示/隐藏吗?
- 是 → 用 v-show
- 否 → 用 v-if
2. 初始状态需要隐藏吗?
- 是,且隐藏是常态 → 用 v-if(节省资源)
- 是,但很快会显示 → 用 v-show
3. 需要保留元素状态吗?
- 是(如表单输入)→ 用 v-show
- 否 → 用 v-if
4. 元素很重(组件复杂)吗?
- 是 → 用 v-if(不显示时完全卸载)
- 否 → 用 v-show
简单说:v-if 是真正的条件渲染,v-show 是 CSS 显示切换。根据你的具体需求选择即可!
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END















暂无评论内容