vue的key簡單理解

看文章後發現key便於理解的兩段話,特此記錄一下。

一、加key與不加key的區別

對實現列表的增刪,若是給列表的每一項增長一個key,即惟一索引,那就能夠很清楚的知道兩個列表誰少了誰沒變。而若是不加key的話,就只能一個個對比,而後進行操做。vue

二、理解key

vue/patch.js,在不帶key的狀況下,判斷sameVnode時由於a.key和b.key都是undefined,對於列表渲染來講已經能夠判斷爲相同節點而後調用patchVnode了,實際根本不會進入到答主給的else代碼,也就無從談起「帶key比不帶key時diff算法更高效」了。node

而後,官網推薦推薦的使用key,應該理解爲「使用惟一id做爲key」。由於index做爲key,和不帶key的效果是同樣的。index做爲key時,每一個列表項的index在變動先後也是同樣的,都是直接判斷爲sameVnode而後複用。(這段話很重要)git

說到底,key的做用就是更新組件判斷兩個節點是否相同。相同就複用,不相同就刪除舊的建立新的。github

正是由於帶惟一key時每次更新都不能找到可複用的節點,不但要銷燬和建立vnode,在DOM裏添加移除節點對性能的影響更大。因此會才說「不帶key可能性能更好」。看下面這個實驗,渲染10w列表項,帶惟一key與不帶key的時間對比:算法

不使用key的狀況:dom

<li v-for="item in list">{{ item.text }}</li>

image.png

使用id做爲key的狀況:性能

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

image

list構造:spa

const list1 = []
  const list2 = []
  for (let i = 0; i <= 100000; i++) {
    list1.push({
      id: i,
      text: i
    })
    list2.push({
      id: i * 2,
      name: 100000 - i
    })
  }

由於不帶key時節點可以複用,省去了銷燬/建立組件的開銷,同時只須要修改DOM文本內容而不是移除/添加節點,這就是文檔中所說的「刻意依賴默認行爲以獲取性能上的提高」。code

既然如此,爲何還要建議帶key呢?由於這種模式只適用於渲染簡單的無狀態組件。對於大多數場景來講,列表組件都有本身的狀態。blog

舉個例子:一個新聞列表,可點擊列表項來將其標記爲"已訪問",可經過tab切換「娛樂新聞」或是「社會新聞」。

不帶key屬性的狀況下,在「娛樂新聞」下選中第二項而後切換到「社會新聞」,"社會新聞"裏的第二項也會是被選中的狀態,由於這裏複用了組件,保留了以前的狀態。要解決這個問題,能夠爲列表項帶上新聞id做爲惟一key,那麼每次渲染列表時都會徹底替換全部組件,使其擁有正確狀態。

這只是個簡單的例子,實際應用會更復雜。帶上惟一key雖然會增長開銷,可是對於用戶來講基本感覺不到差距,並且能保證組件狀態正確,這應該就是爲何推薦使用惟一id做爲key的緣由。至於具體怎麼使用,就要根據實際狀況來選擇了。

相關文章
相關標籤/搜索