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>

四、注意事項

  1. 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>
  1. v-show 不支持 template 標籤:

template 標籤是 “無實體” 的分組標籤,不會被渲染到 DOM 中,而 v-show 需要控制具體元素的 display 屬性,因此不能綁定在 template 上:

<!-- 錯誤寫法 -->
<template v-show="isShow">...</template>

<!-- 正確寫法:綁定在具體元素上 -->
<div v-show="isShow">...</div>
  1. 性能權衡:
    • 若元素切換次數少(如權限菜單、彈窗),用 v-if(初始渲染開銷小);
    • 若元素切換次數多(如 Tab、開關),用 v-show(切換開銷小)。

總結

v-if 是 “動態增刪 DOM”,適合低頻切換、多條件分支場景;v-show 是 “動態控制 CSS”,適合高頻切換、初始顯示場景。兩者核心區別在於 DOM 是否存在和切換開銷,根據實際場景選擇能讓頁面性能更優、邏輯更清晰。記住:“低頻用 v-if,高頻用 v-show” 是最實用的選擇原則。