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 |