Vue3 教學:模板語法 – v-if、v-else-if、v-else 條件渲染
簡介
在 Vue3 中,條件渲染是控制 UI 顯示與隱藏的核心技巧。透過 v-if、v-else-if 與 v-else,開發者可以根據資料狀態動態切換不同的 DOM 結構,而不必在 JavaScript 中手動操作 innerHTML 或 display。這種宣告式的寫法不僅讓程式碼更易讀,也能讓 Vue 的虛擬 DOM 更有效率地進行 diff 與 patch。
在實務開發裡,常見的情境包括:根據使用者權限顯示不同的功能按鈕、在表單驗證失敗時呈現錯誤訊息、或是根據 API 回傳的結果切換「載入中」與「無資料」的畫面。掌握條件渲染的細節,能讓你的介面在 效能 與 可維護性 兩方面都更上一層樓。
核心概念
1. 基本語法:v-if
v-if 會根據綁定的表達式結果(true / false)決定是否在 DOM 中 真正插入 或 移除 該元素。Vue 會在條件變為 false 時,將整個節點與其子樹銷毀,釋放記憶體。
<div id="app">
<p v-if="isLoggedIn">歡迎回來,{{ userName }}!</p>
</div>
const app = Vue.createApp({
data() {
return {
isLoggedIn: false,
userName: 'Alice'
};
}
});
app.mount('#app');
註解:
isLoggedIn為false時,上例的<p>完全不會出現在最終的 HTML 中。
2. v-else-if 與 v-else 的串接
當需要在同一區塊內處理多個互斥條件時,v-else-if 與 v-else 能夠形成「條件鏈」:
<div id="status">
<p v-if="status === 'loading'">載入中…</p>
<p v-else-if="status === 'error'">發生錯誤,請稍後再試。</p>
<p v-else-if="status === 'empty'">目前沒有資料。</p>
<p v-else>資料已成功載入!</p>
</div>
Vue.createApp({
data() {
return {
status: 'loading' // 可切換成 'error'、'empty'、或其他任意字串
};
}
}).mount('#status');
v-else-if必須緊跟在v-if(或另一個v-else-if)之後,且 中間不能有其他元素或註解。v-else為「最後的備案」,只會在所有前置條件皆不成立時渲染。
3. 使用 key 讓條件切換更平滑
在條件切換時,如果同一個元素的結構會改變,建議加上 :key,讓 Vue 能夠正確辨識每一次的「新舊」差異,避免不必要的重渲染。
<div id="toggle">
<button @click="show = !show">切換</button>
<template v-if="show">
<h2 :key="'title-1'">標題 A</h2>
<p :key="'content-1'">內容 A</p>
</template>
<template v-else>
<h2 :key="'title-2'">標題 B</h2>
<p :key="'content-2'">內容 B</p>
</template>
</div>
Vue.createApp({
data() {
return { show: true };
}
}).mount('#toggle');
技巧:
<template>本身不會渲染成實體元素,適合包住多個節點作為條件區塊。
4. v-if 與 v-show 的比較
v-if |
v-show |
|
|---|---|---|
| 渲染時機 | 條件變為 true 時才插入,false 時銷毀 |
初始渲染時即插入,僅透過 display: none 切換 |
| 效能 | 初次渲染較慢,但切換次數少時更佳 | 切換頻繁時較快 |
| 使用情境 | 大區塊、或只會變化一次的內容 | 小區塊、頻繁顯隱的 UI(如 modal) |
5. 多層巢狀條件渲染
在實務中,常會出現「條件裡再套條件」的情況。此時仍建議保持 單一入口(最外層 v-if)的可讀性,避免過度巢狀導致程式碼難以維護。
<div id="profile">
<div v-if="user">
<h3>{{ user.name }}</h3>
<p v-if="user.role === 'admin'">管理員權限</p>
<p v-else-if="user.role === 'editor'">編輯者權限</p>
<p v-else>普通使用者</p>
<p v-if="user.isActive">帳號啟用中</p>
<p v-else>帳號已停用</p>
</div>
<p v-else>載入使用者資訊中…</p>
</div>
常見陷阱與最佳實踐
v-else-if/v-else位置錯誤
必須緊貼在前一個條件元素之後,且不能有任何空格、註解或其他元素插入。否則 Vue 會拋出 “v-else-if/v-else used on element without preceding v-if” 的警告。過度使用
v-if於大量列表
在v-for內同時使用v-if會導致每一次迭代都重新評估條件,效能不佳。建議先透過 計算屬性 產出過濾後的陣列,再渲染。computed: { activeItems() { return this.items.filter(item => item.isActive); } }忘記加
key
在條件切換的區塊裡若包含相同標籤(如<input>),未使用key會導致 Vue 重用舊的 DOM,可能留下舊的值或焦點。條件過於複雜
當條件表達式變得太長或包含多個邏輯運算時,建議抽離成 computed 或 method,保持模板的簡潔。computed: { showError() { return this.status === 'error' && this.retryCount < 3; } }使用
v-if取代 CSS
若只是想「暫時隱藏」而不需要銷毀元素,請選擇v-show或純 CSS(如visibility: hidden),避免不必要的 DOM 重建。
實際應用場景
| 場景 | 為何使用 v-if/v-else-if/v-else |
|---|---|
| 表單驗證錯誤訊息 | 根據每個欄位的驗證結果顯示不同的錯誤文字,錯誤訊息只在需要時渲染,避免多餘的 DOM。 |
| 權限控管 | 依使用者角色 (admin、editor、guest) 動態顯示功能按鈕或管理面板,確保未授權的 UI 不會被載入。 |
| API 載入狀態 | 三段式 (loading → error → data) 的 UI 轉換,使用 v-else-if 把每個狀態封裝成獨立區塊,程式碼易於維護。 |
| 多語系切換 | 根據 locale 的值切換不同的說明文字或日期格式,讓每個語系只在需要時渲染。 |
| 動態表格欄位 | 根據使用者選擇的欄位顯示或隱藏對應的 <th> / <td>,使用 v-if 可避免產生空白欄位。 |
總結
v-if、v-else-if、v-else是 Vue3 中 條件渲染 的核心指令,透過 宣告式 的方式讓 UI 與資料狀態保持同步。- 正確使用 緊鄰、
key與 計算屬性,能避免常見的渲染錯誤與效能瓶頸。 - 在需要 頻繁顯隱 的小區塊時,考慮使用
v-show;在條件較少且區塊較大的情況下,v-if更具效能優勢。 - 透過實務案例(表單驗證、權限控管、API 狀態切換)可以快速把學到的概念落實到專案中,提升程式碼的可讀性與維護性。
掌握了條件渲染,你就能在 Vue3 中寫出 更乾淨、更高效 的介面,為使用者帶來流暢的互動體驗。祝你開發順利,持續探索 Vue 的無限可能!