Vue 中 v-if 與 v-show 的使用方法與區別
在 Vue 中,v-if 和 v-show 是兩個用於控制元素顯示與隱藏的核心指令,就像給元素裝了 “開關”,但兩者的 “開關邏輯” 和適用場景截然不同。掌握它們的用法和區別,能讓我們更合理地控制 DOM 顯示,提升頁面性能。
一、基礎用法
1. v-if:條件渲染(動態創建 / 銷燬 DOM)
v-if 是 “條件渲染” 指令,它會根據表達式的布爾值(true/false)決定是否創建或銷燬DOM 元素。當條件為 false 時,元素會被從 DOM 樹中移除;條件為 true 時,才會創建並插入 DOM。
<template>
<div class="v-if-demo">
<h3>v-if 示例</h3>
<button @click="isShow = !isShow">切換顯示/隱藏</button>
<!-- 條件為true時渲染,false時移除 -->
<div v-if="isShow" class="content">
這是v-if控制的內容(條件為true時才存在於DOM中)
</div>
<!-- v-else 搭配v-if使用,條件相反時渲染 -->
<div v-else class="tip">
內容已隱藏(DOM中無上述content元素)
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isShow = ref(true)
</script>
還可以用v-else-if實現多條件分支渲染:
<template>
<div class="multi-condition">
<input v-model="score" type="number" placeholder="輸入分數">
<div v-if="score >= 90">優秀</div>
<div v-else-if="score >= 60">及格</div>
<div v-else-if="score >= 0">不及格</div>
<div v-else>請輸入有效分數</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const score = ref('')
</script>
2. v-show:條件顯示(僅控制 CSS 顯示狀態)
v-show 是 “條件顯示” 指令,它不會創建或銷燬 DOM 元素,而是通過控制 CSS 的 display 屬性實現顯示 / 隱藏。當條件為 false 時,元素會被添加display: none樣式;條件為 true 時,恢復默認的 display 屬性(如 block、inline 等)。
<template>
<div class="v-show-demo">
<h3>v-show 示例</h3>
<button @click="isVisible = !isVisible">切換顯示/隱藏</button>
<!-- 始終存在於DOM中,僅通過CSS控制顯示 -->
<div v-show="isVisible" class="content">
這是v-show控制的內容(始終存在於DOM中,僅隱藏樣式)
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isVisible = ref(true)
</script>
二、核心區別(關鍵!)
| 特性 | v-if | v-show |
|---|---|---|
| 底層原理 | 動態創建 / 銷燬 DOM 元素 | 控制 CSS 的 display 屬性(DOM 始終存在) |
| 初始渲染開銷 | 條件為 false 時,無渲染開銷(不創建 DOM) | 無論條件是否為 true,都有初始渲染開銷(DOM 已創建) |
| 切換開銷 | 較大(涉及 DOM 增刪,觸發重排重繪) | 極小(僅修改 CSS 樣式,不觸發 DOM 操作) |
| 支持分支 | 支持 v-else、v-else-if 多分支 | 不支持分支,僅單一條件控制 |
| 適用場景 | 切換頻率低、初始條件可能為 false | 切換頻率高、初始條件大概率為 true |
| 特殊元素兼容性 | 可用於 template 標籤(分組渲染) | 不能用於 template 標籤(需綁定具體元素) |
直觀對比:DOM 結構差異
-
當isShow = false(v-if):DOM 樹中沒有被 v-if 控制的 content 元素;
-
當isVisible = false(v-show):DOM 樹中仍有被 v-show 控制的 content 元素,只是添加了style="display: none"。
三、實戰場景選擇
1. 用 v-if 的場景
-
切換頻率低的元素:比如頁面初始化時根據權限顯示的菜單、根據條件展示的表單模塊(如登錄 / 註冊切換,用户大概率只選一種);
-
初始條件為 false 的元素:比如需要用户點擊按鈕才顯示的彈窗(初始不渲染,減少頁面加載壓力);
-
多條件分支渲染:比如根據狀態展示不同的提示文案、操作按鈕。
示例:權限控制菜單
<template>
<nav class="menu">
<div>首頁</div>
<!-- 僅管理員可見(切換頻率低,用v-if) -->
<div v-if="userRole === 'admin'">用户管理</div>
<div v-if="userRole === 'admin'">系統設置</div>
<div>個人中心</div>
</nav>
</template>
<script setup>
import { ref } from 'vue'
const userRole = ref('admin') // 實際從登錄狀態獲取
</script>
2. 用 v-show 的場景
-
切換頻率高的元素:比如 Tab 切換、按鈕點擊顯示 / 隱藏的內容、下拉菜單(頻繁切換,需低開銷);
-
初始條件為 true 的元素:比如頁面默認顯示的列表,用户可能頻繁切換顯示 / 隱藏(避免頻繁 DOM 操作)。
示例:頻繁切換的 Tab 面板
<template>
<div class="tab-container">
<button @click="activeTab = 'tab1'" :class="{ active: activeTab === 'tab1' }">Tab1</button>
<button @click="activeTab = 'tab2'" :class="{ active: activeTab === 'tab2' }">Tab2</button>
<button @click="activeTab = 'tab3'" :class="{ active: activeTab === 'tab3' }">Tab3</button>
<!-- 頻繁切換,用v-show(低切換開銷) -->
<div v-show="activeTab === 'tab1'" class="tab-content">Tab1 內容</div>
<div v-show="activeTab === 'tab2'" class="tab-content">Tab2 內容</div>
<div v-show="activeTab === 'tab3'" class="tab-content">Tab3 內容</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
</script>
四、注意事項
- v-if 與 v-for 不能同時使用在同一個元素上:
v-for 的優先級高於 v-if,會導致每次循環都執行 v-if 判斷,性能極差。如需篩選循環數據,應先通過 computed 過濾數據,再用 v-for 渲染:
<!-- 錯誤寫法:v-for和v-if同元素 -->
<li v-for="item in list" :key="item.id" v-if="item.isValid">...</li>
<!-- 正確寫法:先過濾數據 -->
<script setup>
const validList = computed(() => list.value.filter(item => item.isValid))
</script>
<template>
<li v-for="item in validList" :key="item.id">...</li>
</template>
- v-show 不支持 template 標籤:
template 標籤是 “無實體” 的分組標籤,不會被渲染到 DOM 中,而 v-show 需要控制具體元素的 display 屬性,因此不能綁定在 template 上:
<!-- 錯誤寫法 -->
<template v-show="isShow">...</template>
<!-- 正確寫法:綁定在具體元素上 -->
<div v-show="isShow">...</div>
- 性能權衡:
-
- 若元素切換次數少(如權限菜單、彈窗),用 v-if(初始渲染開銷小);
-
- 若元素切換次數多(如 Tab、開關),用 v-show(切換開銷小)。
總結
v-if 是 “動態增刪 DOM”,適合低頻切換、多條件分支場景;v-show 是 “動態控制 CSS”,適合高頻切換、初始顯示場景。兩者核心區別在於 DOM 是否存在和切換開銷,根據實際場景選擇能讓頁面性能更優、邏輯更清晰。記住:“低頻用 v-if,高頻用 v-show” 是最實用的選擇原則。