key
vue官網(wǎng)推薦我們使用v-for時劝篷,給每一個節(jié)點元素添加一個唯一的 key
,其實不只是vue民宿,react中在執(zhí)行列表渲染時也會要求給每個組件添加上key這個屬性娇妓。
要了解key的作用,首先我們要簡單了解一下虛擬DOM的Diff算法
vue和react都實現(xiàn)了一套虛擬DOM活鹰,使我們可以不直接操作DOM元素哈恰,只操作數(shù)據(jù)便可以重新渲染頁面。而隱藏在背后的原理便是其高效的Diff算法志群。
vue和react的虛擬DOM的Diff算法大致相同着绷,其核心是基于兩個簡單的假設:
1. 兩個相同的組件產(chǎn)生類似的DOM結構,不同的組件產(chǎn)生不同的DOM結構锌云。
2. 同一層級的一組節(jié)點蓬戚,他們可以通過唯一的id進行區(qū)分。
基于以上這兩點假設宾抓,使得虛擬DOM的Diff算法的復雜度從O(n^3)降到了O(n)子漩。
好吧,這樣解釋石洗,似乎有點籠統(tǒng)了幢泼,我們來看一個例子:
我們希望可以在B和C之間加一個F,
Diff算法默認執(zhí)行起來是這樣的:
就是C更新成F讲衫,D更新成C缕棵,E更新成D,最后再插入E
所以我們需要使用key來給每個節(jié)點做一個唯一標識涉兽,Diff算法就可以正確的識別此節(jié)點招驴,找到正確的位置區(qū)插入新的節(jié)點。
所以一句話枷畏,key的作用主要是為了高效的更新虛擬DOM
寫一個案例:
<div id="app">
<ul>
沒有加key
<li v-for="item in arr">
<input type="checkbox"/>{{item}}
</li>
<button @click="add">添加</button>
</ul>
<ul>
沒有加key
<li v-for="item in arr" :key="item">
<input type="checkbox"/>{{item}}
</li>
<button @click="add">添加</button>
</ul>
</div>
<script>
new Vue({
data(){
return{
arr:["a","b","c","d","e"]
}
},
methods:{
add(){
this.arr.splice(2,0,'f')
}
}
}).$mount("#app")
</script>
先選中C别厘,當沒有加key的插入F的時候,選中的狀態(tài)變化
可以看的出來拥诡,算法是直接將C變成了F
那么我們再來看下触趴,加了key的效果:
加了,算法可以準確無誤的在b和c之間添加了一個f
數(shù)組方法
當數(shù)據(jù)發(fā)生變化時渴肉,Vue會自動檢測數(shù)據(jù)的變化冗懦,視圖會發(fā)生對應的更新。
Vue中包含了一組觀察數(shù)組編譯的方法仇祭,使用它們改變數(shù)組也會觸發(fā)視圖的更新
變異方法:會改變原始數(shù)組
非變異方法:不會改變原始數(shù)組披蕉,但是會返回一個新數(shù)組
- fliter()
- slice()
- concat()
<div id="app">
<ul>
<li v-for="item in arr" :key="item">{{item}}</li>
<button @click="add()">添加</button>
</ul>
</div>
<script>
new Vue({
data(){
return{
arr:["王者榮耀","絕地求生","c","d","e"]
}
},
methods:{
add(){
// push
// this.arr.push("全軍出擊", "aa0", "bb");
// pop
// this.arr.pop()
// shift 刪除數(shù)組中的第一個元素
// this.arr.shift()
//
// this.arr.unshift("123")
// this.arr.splice(1,2)
// this.arr.splice(1,0, "456","567")
// this.arr.splice(1,2, "456","567")
// 這樣修改數(shù)組中的元素,視圖是不會更新的
// this.arr[1] = "999"
// 使用vue的set方法更新
// 全局set
// Vue.set(this.arr, 1, "999")
// 當前實例set
this.$set(this.arr, 1, "888")
}
}
}).$mount("#app")
</script>
直接修改數(shù)組中的元素,視圖是不會更新的没讲,需要用到Vue中的set方法
// 這樣修改數(shù)組中的元素承冰,視圖是不會更新的
// this.arr[1] = "999"
// 使用vue的set方法更新
// 全局set
// Vue.set(this.arr, 1, "999")
// 當前實例set
this.$set(this.arr, 1, "888")