定義
-
key 的特殊 attribute 主要用在 Vue 的虛擬 DOM 算法,在新舊 nodes 對比時辨識 VNodes。如果不使用 key,Vue 會使用一種最大限度減少動態元素並且儘可能的嘗試就地修改/複用相同類型元素的算法。而使用 key 時,它會基於 key 的變化重新排列元素順序,並且會移除 key 不存在的元素。
-
當 Vue 正在更新使用 v-for 渲染的元素列表時,它默認使用“就地更新”的策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序,而是就地更新每個元素
示例
<div id="app">
<div>
<input type="text" v-model="name">
<button @click="unshift">前面添加</button>
<button @click="push">後面添加</button>
<button @click="splice">在第2條後添加</button>
<button @click="exchange">第一條li與第二條互換</button>
</div>
<ul>
<li>沒有key</li>
<li v-for="(item, i) in list">
<input type="checkbox"> {{item.name}}
</li>
</ul>
<hr>
<ul>
<li>key="i"</li>
<li v-for="(item, i) in list" :key="i">
<input type="checkbox"> {{item.name}}
</li>
</ul>
<hr>
<ul>
<li>key="item.id"</li>
<li v-for="(item, i) in list" :key="item.id">
<input type="checkbox"> {{item.name}}
</li>
</ul>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [{
id: 1,
name: '李斯'
},
{
id: 2,
name: '呂不韋'
},
{
id: 3,
name: '嬴政'
}
]
},
methods: {
unshift() {
this.list.unshift({
id: ++this.newId,
name: this.name
})
this.name = ''
},
push() {
this.list.push({
id: ++this.newId,
name: this.name
})
this.name = ''
},
splice() {
this.list.splice(2,0,{
id: ++this.newId,
name: this.name
})
this.name = ''
},
exchange() {
const del = this.list.splice(1,1);
this.list.unshift(del[0]);
}
}
});
</script>
當選中呂不爲時,前面添加楠楠
當選中呂不爲時,後面添加楠楠
當選中呂不爲時,在第二條後添加楠楠
第一條li與第二條互換
結論
key的作用就是更新組件時判斷兩個節點是否相同。相同就複用,不相同就刪除舊的創建新的。如果不添加key組件默認都是就地複用,不會刪除添加節點,只是改變列表項中的文本值,要知道節點操作是十分耗費性能的。而添加了key之後,當對比內容不一致時,就會認爲是兩個節點,會先刪除掉舊節點,然後添加新節點。
- 沒有key時,前3個節點複用,只修改值,在最後添加了一個新節點
- key="i"時,當新節點的key與舊的key相同時,則複用舊節點,key爲0,1,2的節點會複用舊節點,選中的節點爲key=“1”,
- key="item.id"時,此id爲唯一值,所以其它3箇舊節點都會複用
-
如果只是交換順序,key用 i 或者不用的性能比較好,因爲只是改變節點的值,這個默認的模式是高效的,但是隻適用於不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。
-
如果會增刪數據,key用唯一標識的性能比較好,vue根據這唯一的key跟蹤每個節點的身份,從而重用和重新排序現有元素,新節點的key與舊節點key相同時,會直接複用
其它用法
<transition>
<span :key="text">{{ text }}</span>
</transition>
當 text 發生改變時, 總是會被替換而不是被修改,因此會觸發過渡。