標籤:

Vue2.0 v-for 中 :key 到底有什麼用?

Vue2.0 v-for 中 :key 到底有什麼用? 當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用 「就地復用」 策略 。 這句話是什麼意思? 不用:key 時有什麼問題? 最好給個例子。


其實不只是vue,react中在執行列表渲染時也會要求給每個組件添加上key這個屬性。

要解釋key的作用,不得不先介紹一下虛擬DOM的Diff演算法了。

我們知道,vue和react都實現了一套虛擬DOM,使我們可以不直接操作DOM元素,只操作數據便可以重新渲染頁面。而隱藏在背後的原理便是其高效的Diff演算法。

vue和react的虛擬DOM的Diff演算法大致相同,其核心是基於兩個簡單的假設:

1. 兩個相同的組件產生類似的DOM結構,不同的組件產生不同的DOM結構。

2. 同一層級的一組節點,他們可以通過唯一的id進行區分。

基於以上這兩點假設,使得虛擬DOM的Diff演算法的複雜度從O(n^3)降到了O(n)

這裡我們借用React』s diff algorithm中的一張圖來簡單說明一下:

當頁面的數據發生變化時,Diff演算法只會比較同一層級的節點:

如果節點類型不同,直接幹掉前面的節點,再創建並插入新的節點,不會再比較這個節點以後的子節點了。

如果節點類型相同,則會重新設置該節點的屬性,從而實現節點的更新。

當某一層有很多相同的節點時,也就是列表節點時,Diff演算法的更新過程默認情況下也是遵循以上原則。

比如一下這個情況:

我們希望可以在B和C之間加一個F,Diff演算法默認執行起來是這樣的:

即把C更新成F,D更新成C,E更新成D,最後再插入E,是不是很沒有效率?

所以我們需要使用key來給每個節點做一個唯一標識,Diff演算法就可以正確的識別此節點,找到正確的位置區插入新的節點。

所以一句話,key的作用主要是為了高效的更新虛擬DOM。另外vue中在使用相同標籤名元素的過渡切換時,也會使用到key屬性,其目的也是為了讓vue可以區分它們,否則vue只會替換其內部屬性而不會觸發過渡效果。

內容由 58招聘FE 朱雀 提供

圖片來自於網路

參考文獻

過渡效果 - vue.js列表渲染 - vue.jsReact』s diff algorithm


呵呵,因為key,所以在github上提過兩個issues,結果大神一句沒有加key駁回。

想想也是傷心。

肯定是diff的機制也讓大神很為難。

但是後期發現兩個相鄰的button都會因為沒有加key,而產生錯亂,想想也是更傷心了。

剛看到問題問不用:key時有什麼問題,我把之前寫的Demo放出來,用了key也於事無補......

==》用例《==

點擊add * 3,點擊後面兩個 Click me! , 點擊第一個刪除,奇蹟會出現。


簡單的說就是為了提高遍歷性能


vue沒用過,不過還是想答,感覺差不多。ng-repeat的時候,track by ,react裡面的map時候index索引。ng是遍曆數據層級淺的情況要添加,不然ng自動索引的可能會亂,層級深的沒這問題。react循環遍歷也需要加一個索引,屬性名我忘了,也是類似防它自動添加導致衝突。


推薦閱讀:

關於vue-loader無法為動態添加的元素添加scoped style的解決方案?
單向數據綁定和雙向數據綁定的優缺點,適合什麼場景?
vuejs的.vue文件中的style標籤中的css樣式,背景圖路徑不對?
JSP渲染比Ajax渲染更安全?(阿里的大神讓我放棄Ajax的想法,說ajax存在安全缺陷)?

TAG:Vuejs |