前言 - Prologue
嘗試 30 天寫文充實版面 (跳過特休假跟假日 ლ(́◕◞౪◟◕‵ლ) ) 不間斷更新文章的 Day 12
Vue 中的 key
屬性是一個重要的概念,理解 key
屬性的使用方法和原則,可以提高應用程序的性能和渲染效率,同時也可以避免出現一些奇怪的錯誤。
本文將介紹 Vue 中 key
屬性的使用方法、作用、原則、注意事項,並通過示例來說明綁定唯一識別值作為 key
屬性的優點和避免綁定 index 的原因。
正文 - Main text
所以到底為什麼 Vue 中 key 值不能綁定 index?大家是不是歧視它? 不是啦,下面將會以文例解釋大概為什麼。
在 Vue 中,當一個元素在 v-for
循環渲染時,通常需要設置一個 key
屬性來幫助 Vue 識別元素。
key
屬性是一個特殊的屬性,用於渲染列表時更新元素順序和狀態的跟蹤,作用是協助 Vue 辨識每個 Virtual DOM 的狀態,以便在 Virtual DOM 中進行高效的更新操作。
Virtual DOM (虛擬 DOM):不是一個真正的 DOM。DOM 是由瀏覽器所產生,並存在在瀏覽器當中的資料結構,而 Virtual DOM 本身是一個 JavaScript 的物件,存在在 memory 當中。
通常情況下,我們會把 key
屬性綁定為列表資料的索引,例如:
<ul>
<li v-for="(item, index) in items" :key="index">
{{ item }}
</li>
</ul>
但是如果資料項目的順序會發生變化,或者新增或刪除元素,這樣的寫法會導致性能下降,因為 Vue 需要重新創建、刪除、更新每個元素。
Vue 的 Virtual DOM 會將每個元素和其對應的 key
屬性值存儲在內部映射表中,以便能夠快速找到該元素的位置,以便進行相應的操作。所以如果列表中的項目不是按照它們的索引值順序排列,而是插入、刪除或者移動的話,會導致內部映射表失效,進而觸發 DOM 的重新渲染。這樣就會降低性能,增加程式碼的複雜度。
而如果將 key
屬性綁定為唯一的識別值,例如列表項目的 ID 或其他唯一的屬性,可以確保它們在重新渲染時能夠被正確地比對。如果不知道項目的唯一值,可以使用一些雜湊函式來生成一個唯一的 key
。
下方為一個使用 ID 為 key
的示例:
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
這樣的寫法可以保證當資料產生變化時,只有必要的元素會被重新渲染,從而提高了性能。
總結而言兩點:
- 使用索引 (index) 綁定 key 屬性並重新排列項目
項目的順序發生了變化,但是列表沒有正確地重新渲染。這是因為 Vue 認為索引相同的項目仍然是相同的項目,不需要重新渲染。這導致列表中的元素順序錯亂,並且渲染的項目也不正確。
每個項目都正確地重新渲染,並且列表的順序也正確。這是因為每個項目都有唯一的識別值,Vue 可以正確地比對項目,確定哪些項目需要重新渲染,哪些項目可以保持不變。
因此建議在使用 v-for
時,綁定唯一的識別值作為 key
屬性,以確保在列表項目被重新排列或者有項目被新增或刪除時,Vue 可以正確地比對項目並且進行必要的重新渲染。這樣可以提高應用程序的性能和渲染效率,同時也可以避免出現一些奇怪的錯誤。
如果沒有綁定唯一的識別值作為 key
屬性,可能會導致列表項目渲染錯誤、重複渲染項目、應用程序性能下降等問題。在使用 v-for
渲染列表時,建議在渲染項目時綁定唯一的識別值作為 key 屬性。
例如要渲染一個帶有 v-for 的列表,可以這樣寫:
<template>
<div>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
{ id: 4, name: 'Item 4' },
{ id: 5, name: 'Item 5' },
],
};
},
};
</script>
在這個示例中,每個項目都有唯一的識別值 id
,因此我們可以使用 item.id
作為 key
屬性的值。這樣做可以確保在列表項目被重新排列或者有項目被新增或刪除時,Vue 可以正確地比對項目並且進行必要的重新渲染。
以下是一些使用 key 屬性的原則和注意事項:
- 綁定唯一識別值:
key
屬性應該綁定唯一識別值,例如資料庫中的 id,而不是資料集合中的索引 (index)。
- 相同的 key 屬性值應該具有相同的意義:如果使用相同的
key
屬性值來渲染不同的數據,可能會導致意外的錯誤。
- 不要使用動態生成的內容作為 key:使用動態生成的內容作為
key
可能會導致不必要的更新。例如:使用 Math.random()
生成的隨機數作為 key
可能會導致元件在每次渲染時都被視為不同的元件。
- 不要過度使用 v-if 和 v-for 指令:在同一元素上同時使用
v-if
和 v-for
指令可能會導致不必要的更新。
後記 - Epilogue
因為面試遇到這個問題後... 非常想了解到底為什麼不可以 key
綁 index 的確切原因 (OS: 超好奇想知道RRR 求知慾爆棚),雖然之前有因為 key
踩過雷有改成採用 id 當作 key 值,但沒有深入去了解到底為什麼使用 key
不可以綁索引值 (index) )。
透過訪問各種貼文後理解了 key
屬性應該綁定唯一識別值,而不是索引值 (index),因為索引在資料集合發生變化時可能會改變,從而導致不必要的更新。
而 Vue 中的 key
屬性不僅可以提高應用程序的性能和渲染效率,還可以幫助我們更好地管理和維護代碼,降低代碼的複雜度和維護成本。