Released 2023-02-23

Modified 2023-02-23

Tech

1663Words (9min read)

[Day 12] 為什麼 Vue 中 key 值不能綁定 index? - 嘗試 30 日寫文充版挑戰

Title Image

前言 - 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 認為索引相同的項目仍然是相同的項目,不需要重新渲染。這導致列表中的元素順序錯亂,並且渲染的項目也不正確。

  • 使用唯一值綁定 key 屬性並重新排列項目

每個項目都正確地重新渲染,並且列表的順序也正確。這是因為每個項目都有唯一的識別值,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-ifv-for 指令可能會導致不必要的更新。

後記 - Epilogue

因為面試遇到這個問題後... 非常想了解到底為什麼不可以 key 綁 index 的確切原因 (OS: 超好奇想知道RRR 求知慾爆棚),雖然之前有因為 key 踩過雷有改成採用 id 當作 key 值,但沒有深入去了解到底為什麼使用 key 不可以綁索引值 (index) )。

透過訪問各種貼文後理解了 key 屬性應該綁定唯一識別值,而不是索引值 (index),因為索引在資料集合發生變化時可能會改變,從而導致不必要的更新。

而 Vue 中的 key 屬性不僅可以提高應用程序的性能和渲染效率,還可以幫助我們更好地管理和維護代碼,降低代碼的複雜度和維護成本。

[Day 12] 為什麼 Vue 中 key 值不能綁定 index? - 嘗試 30 日寫文充版挑戰

https:///en/blog/19

Author

Kama

Read more from Tech
lightbox-image
Toggle Button - Red Pandas Icons by svgrepo.com

Copyrights © 2023 Kama, All Rights Reserved.