爲什麼要在列表組件裏寫 Key ?

答案:主要是爲了提升同級的比較效率的。

借用我在博客上另外一篇 Vue 2 渲染過程的圖

其中核心比對邏輯就是新老節點頭對頭,頭對尾,尾對頭,尾對尾,都判定非 sameVnode,則拿着 key 去比對,若其中有被判定爲 sameVnode,則複用節點。反之需要刪除後再添加新節點。

function sameVnode(a, b) {
  // key,tag,isComment相同,並且data都不爲空,並且節點類型不是input
  return (
    a.key === b.key && (
      (
        a.tag === b.tag &&
        a.isComment === b.isComment &&
        isDef(a.data) === isDef(b.data) &&
        sameInputType(a, b)
      ) || (
        isTrue(a.isAsyncPlaceholder) &&
        a.asyncFactory === b.asyncFactory &&
        isUndef(b.asyncFactory.error)
      )
    )
  )
}

那麼有個問題,能複用節點一定就快嗎?不一定,設你需要渲染 10w 條列表數據

<li v-for="item in list" :key="item.id">{{ item.name }}</li>

list = [
  {
    id: 1,
    name: 1
  },
  ......
  {
    id: 100000,
    name: 100000
  }
]

若不寫 key,新老節點的 key 都是 undefined 相同。tag ,isComment相同,且 data 不爲空。那li 節點也都被判定爲 sameVnode,只需要迭代替換文本節點就可以了。

但若寫了 key,新老節點部分 key 不相同。判定爲 sameVnode 的部分照樣去替換文本節點,然而 key 不相同的部分還得創建/刪除 DOM 節點,花銷自然比不寫 key 大。

但這種場景只適用於簡單的無狀態組件,vue 還是推薦使用 key,這是因爲開發中遇到的大多數場景,都有自己的狀態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章