Vue中key的作用
阿新 • • 發佈:2020-06-09
# Vue中key的作用
`key`的特殊`attribute`主要用在`Vue`的虛擬`DOM`演算法,在新舊`Nodes`對比時辨識`VNodes`。如果不使用`key`,`Vue`會使用一種最大限度減少動態元素並且儘可能的嘗試就地修改、複用相同型別元素的演算法,而使用`key`時,它會基於`key`的變化重新排列元素順序,並且會移除`key`不存在的元素。此外有相同父元素的子元素必須有獨特的`key`,重複的`key`會造成渲染錯誤。
## 描述
首先是官方文件的描述,當`Vue`正在更新使用`v-for`渲染的元素列表時,它預設使用就地更新的策略,如果資料項的順序被改變,`Vue`將不會移動`DOM`元素來匹配資料項的順序,而是就地更新每個元素,並且確保它們在每個索引位置正確渲染。這個預設的模式是高效的,但是隻適用於不依賴子元件狀態或臨時`DOM`狀態的列表渲染輸出,例如表單輸入值。為了給`Vue`一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 `key attribute`,建議儘可能在使用`v-for`時提供`key attribute`,除非遍歷輸出的`DOM`內容非常簡單,或者是刻意依賴預設行為以獲取效能上的提升。
簡單來說,當在列表迴圈中使用`key`時,需要使用`key`來給每個節點做一個唯一標識,`diff`演算法就可以正確的識別此節點,找到正確的位置直接操作節點,儘可能地進行重用元素,`key`的作用主要是為了高效的更新虛擬`DOM`。此外,使用`index`作為`key`是並不推薦的做法,其只能保證`Vue`在資料變化時強制更新元件,以避免原地複用帶來的副作用,但不能保證最大限度的元素重用,且使用`index`作為`key`在資料更新方面和不使用`key`的效果基本相同。
## 示例
首先定義一個`Vue`例項,渲染四個列表,分別為簡單列表與複雜列表,以及其分別攜帶`key`與不攜帶`key`時對比其更新渲染時的速度,本次測試使用的是`Chrome 81.0`,每次在`Console`執行程式碼時首先會進行重新整理重新載入介面,避免瀏覽器以及`Vue`自身優化帶來的影響。
```html
Vue
console.timeEnd());
// default: 2.193056640625ms
```
```javascript
// 存在key的情況下
console.time();
vm.simpleListWithKey = [5, 6, 7, 8, 9, 10, 11, 12];
vm.$nextTick(() => console.timeEnd());
// default: 3.2138671875ms
```
原地複用可能會帶來一些副作用,文件中提到原地複用這個預設的模式是高效的,但是隻適用於不依賴子元件狀態或臨時`DOM`狀態的列表渲染輸出,例如表單輸入值。在不設定`key`的情況下,元素中沒有與資料`data`繫結的部分,`Vue`會預設使用已經渲染的`DOM`,而綁定了資料`data`的部分會進行跟隨資料渲染,假如操作了元素位置,則元素中未繫結`data`的部分會停留在原地,而綁定了`data`的部分會跟隨操作進行移動,在下面的例子中首先需要將兩個`A`之後的輸入框新增資料資訊,這樣就製作了一個臨時狀態,如果此時點選下移按鈕,那麼不使用`key`的組中的輸入框將不會跟隨下移,且`B`到了頂端併成為了紅色,而使用`key`的組中會將輸入框進行下移,且`A`依舊是紅色跟隨下移。
```html
就地複用
console.timeEnd());
vm.$nextTick(() => console.timeEnd());
// default: 4.100244140625ms
```
```javascript
console.time();
vm.complexListWithKey = [
{id: 3, list: [7, 8, 9]},
{id: 2, list: [4, 5, 6]},
{id: 1, list: [1, 2, 3]},
];
vm.$nextTick(() => console.timeEnd());
// default: 3.016064453125ms
```
## 每日一題
```
https://github.com/WindrunnerMax/EveryDay
```
## 參考
```
https://cn.vuejs.org/v2/api/#key
https://www.jianshu.com/p/4bdd2690859c
https://www.zhihu.com/question/61078310
https://segmentfault.com/a/1190000012861862
https://www.cnblogs.com/zhumingzhenhao/p/7688336.html
https://blog.csdn.net/hl18730262380/article/details/89306500
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/1
https://cn.vuejs.org/v2/guide/list.html#%E7%BB%B4%E6%8A%A4%E7%8A%B6%E6%80
- {{item}}
- {{item}}
- 5">{{value}}
- 5">{{value}}