如果有任何問題或建議,歡迎隨時聯繫我:
大家好!昨天我們一起探索了 Vue 的互動核心 v-bind
和 v-on
,學會了如何讓資料與畫面同步、如何傾聽使用者的操作。現在,我們的應用程式已經有了「互動」的能力。
今天,我們要更進一步,學習如何控制畫面的「結構」。你會學到如何根據不同的條件,決定一個元素是否應該出現在畫面上 (條件渲染),以及如何根據一組資料,動態地產生一整個列表的元素 (列表渲染)。
這兩個強大的指令——v-if
和 v-for
——是所有動態介面的基石。掌握它們,你就能從只能做「靜態頁面」的開發者,蛻變為能打造「動態應用」的工程師。
在開發中,我們經常需要根據某個狀態來決定是否顯示某個區塊。例如:
這就是 v-if
的主場。
v-if
, v-else
, v-else-if
:非黑即白,或多重選擇v-if
會根據一個布林值的表達式來決定是否渲染一個元素。如果表達式為 true
,元素就會被建立並插入 DOM;如果為 false
,元素就會被銷毀。
<script setup>
import { ref } from 'vue';
const isLoggedIn = ref(false);
</script>
<template>
<button @click="isLoggedIn = !isLoggedIn">
{{ isLoggedIn ? '登出' : '登入' }}
</button>
<div v-if="isLoggedIn">
<p>歡迎回來,VIP 使用者!</p>
</div>
<div v-else>
<p>請先登入以查看更多內容。</p>
</div>
</template>
在這個例子中,
div
的顯示與否完全由isLoggedIn
這個 ref 變數控制。v-else
則提供了一個「備案」,它必須緊跟在v-if
或v-else-if
的元素後面。
v-if
vs v-show
:真正的銷毀 vs 單純的隱藏Vue 提供了另一個指令 v-show
,它也能根據條件控制元素的可見性。但它和 v-if
有個關鍵的區別:
v-if
是 「真正的」條件渲染。如果條件為假,對應的元素會被完全從 DOM 中移除。當條件變為真時,才會重新建立、編譯、並掛載元素。v-show
則是 基於 CSS 的切換。無論條件是真是假,元素始終會被渲染在 DOM 中。v-show
只是簡單地切換元素的 display: none;
CSS 屬性。該用哪個?
v-if
有更高的「切換開銷」,因為它涉及 DOM 的新增和刪除。v-show
有更高的「初始渲染開銷」,因為它一開始就需要把元素渲染出來。v-show
效能會更好。如果條件 很少改變(例如,使用者登入狀態),或者你希望確保在條件為假時,元素內的組件完全不會被渲染或執行,那麼 v-if
是更合適的選擇。v-for
讓我們可以基於一個陣列來渲染一個列表。它的語法是 item in items
,非常直觀。
:key
的重要性假設我們有一個待辦事項清單:
<script setup>
import { ref } from 'vue';
const todos = ref([
{ id: 1, text: '學習 Vue' },
{ id: 2, text: '撰寫鐵人賽文章' },
{ id: 3, text: '休息一下' }
]);
</script>
<template>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
</template>
v-for
會遍歷todos
陣列,為每個todo
物件渲染一個<li>
元素。
注意到了嗎?那個 :key
是什麼?
key
是 Vue 用來識別 VDOM 中每個節點的「身份證」。當你的資料列表更新時(例如新增、刪除、或重新排序),Vue 會使用 key
來匹配新舊節點,以決定如何最高效地更新 DOM。
key
? 如果沒有 key
,Vue 會採用一種「就地更新」的策略,它會盡量複用相同位置的元素,只更新其內容。這在某些情況下會導致非預期的行為,尤其是在列表包含表單輸入或子組件時。index
當 key
? v-for
也提供 (item, index) in items
的語法來獲取索引。但使用 index
作為 key
是非常危險的。想像一下,你刪除了列表中的第一項,原本 index
為 1 的項目現在變成了 index
0,index
為 2 的變成了 1... 所有 key
都亂掉了!這會讓 Vue 感到困惑,可能導致錯誤的 DOM 更新,效能也更差。最佳實踐:永遠為 v-for
綁定一個 唯一且穩定 的 key
,通常是來自你資料的 id
。
v-if
與 v-for
一起用?請三思!一個常見的錯誤是把 v-if
和 v-for
放在同一個元素上。
<!-- ❌ 不推薦的寫法 -->
<li v-for="user in users" v-if="user.isActive" :key="user.id">
{{ user.name }}
</li>
為什麼不好? 因為在 Vue 中,v-for
的優先級比 v-if
更高。這意味著,Vue 會先遍歷 所有 的 users
,然後在每次迭代中再用 v-if
進行判斷。如果你的 users
陣列有一千個項目,但只有十個是 isActive
的,你依然會遍歷一千次!
正確的做法:
使用 computed
屬性(推薦):先在 <script>
中把列表過濾好,再用 v-for
渲染過濾後的結果。這讓模板保持乾淨,且效能更好。
const activeUsers = computed(() => {
return users.value.filter(user => user.isActive);
});
<!-- ✅ 推薦的寫法 -->
<li v-for="user in activeUsers" :key="user.id">
{{ user.name }}
</li>
使用 <template>
包裝:如果你不想用 computed
,可以將 v-if
移到外層的 <template>
標籤上。
<template v-for="user in users" :key="user.id">
<li v-if="user.isActive">
{{ user.name }}
</li>
</template>
思考一:v-if
vs v-show
的抉擇
假設你在設計一個有「編輯模式」和「預覽模式」的個人資料頁面。使用者可以點擊一個按鈕來回切換這兩種模式。你會選擇用 v-if
還是 v-show
來控制這兩個模式的顯示與隱藏?為什麼?
思考二:key
的威力
想像一個可以讓使用者自由拖曳排序的任務列表。如果這個列表的 v-for
是用 index
作為 key
,當使用者拖曳交換了兩個任務的位置後,你覺得 Vue 的更新過程會發生什麼事?如果改用任務的 id
作為 key
,又會如何不同?
今天我們學會了 Vue 中控制 DOM 結構的兩大指令:v-if
和 v-for
。它們讓我們能夠根據應用程式的狀態,動態地新增、移除或渲染元素列表。
掌握它們的用法與之間的差異,特別是 v-if
與 v-show
的選擇,以及為 v-for
提供穩定 key
的重要性,是寫出高效能、可預測 Vue 應用的關鍵。
本日關鍵字回顧
v-if
, v-else
, v-else-if
: 條件渲染,會實際新增或銷毀 DOM 節點。v-show
: 條件顯示,透過 CSS display
屬性控制可見性。v-for
: 列表渲染,用於遍歷陣列並產生元素。:key
: 節點的唯一身份標識,對高效的 DOM 更新至關重要。v-for
與 v-if
的優先級: v-for
高於 v-if
,避免在同一元素上同時使用。明天,我們將進入 Vue 最迷人的核心概念之一:組件化。我們將學習如何把介面拆分成一個個可複用的積木,敬請期待!