說到這個問題想必要舉個例子了
image
沒有key的情況:
<div id="app">
<div>
<input type="text" v-model="name">
<button @click="add">添加</button>
</div>
<ul>
<li v-for="(item, i) in list">
<input type="checkbox"> {{item.name}}
</li>
</ul>
<script>
// 創建 Vue 實例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [
{ id: 1, name: '李斯' },
{ id: 2, name: '呂不韋' },
{ id: 3, name: '嬴政' }
]
},
methods: {
add() {
//注意這裏是unshift
this.list.unshift({ id: ++this.newId, name: this.name })
this.name = ''
}
}
});
</script>
</div>
當選中呂不爲時,添加楠楠後選中的確是李斯,並不是我們想要的結果,我們想要的是當添加楠楠後,一種選中的是呂不爲
key1.jpg
key3.jpg
有key
<div id="app">
<div>
<input type="text" v-model="name">
<button @click="add">添加</button>
</div>
<ul>
<li v-for="(item, i) in list" :key="item.id">
<input type="checkbox"> {{item.name}}
</li>
</ul>
<script>
// 創建 Vue 實例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [
{ id: 1, name: '李斯' },
{ id: 2, name: '呂不韋' },
{ id: 3, name: '嬴政' }
]
},
methods: {
add() {
//注意這裏是unshift
this.list.unshift({ id: ++this.newId, name: this.name })
this.name = ''
}
}
});
</script>
</div>
同樣當選中呂不爲時,添加楠楠後依舊選中的是呂不爲。
key1.jpg
key2.jpg
可以簡單的這樣理解:加了key(一定要具有唯一性) id的checkbox跟內容進行了一個關聯。是我們想達到的效果
查過相關文檔,圖例說明很清晰。
vue和react的虛擬DOM的Diff算法大致相同,其核心是基於兩個簡單的假設
首先講一下diff算法的處理方法,對操作前後的dom樹同一層的節點進行對比,一層一層對比,如下圖:
before.png
當某一層有很多相同的節點時,也就是列表節點時,Diff算法的更新過程默認情況下也是遵循以上原則。
比如一下這個情況:
3297464-ee627869a6714336.jpg
我們希望可以在B和C之間加一個F,Diff算法默認執行起來是這樣的:
3297464-d912523aac5fd108.jpg
即把C更新成F,D更新成C,E更新成D,最後再插入E,是不是很沒有效率?
所以我們需要使用key來給每個節點做一個唯一標識,Diff算法就可以正確的識別此節點,找到正確的位置區插入新的節點。
3297464-650689b4bd4b9eb6.jpg
vue中列表循環需加:key="唯一標識" 唯一標識可以是item裏面id index等,因爲vue組件高度複用增加Key可以標識組件的唯一性,爲了更好地區別各個組件 key的作用主要是爲了高效的更新虛擬DOM