<!DOCTYPE html>
<html>
<head>
<title>03-key的作用及原理</title>
</head>
<body>
<div id="demo">
<p v-for="item in items" :key="item">{{item}}</p>
</div>
<script src="../../dist/vue.js"></script>
<script>
// 創(chuàng)建實(shí)例
const app = new Vue({
el: '#demo',
data: { items: ['a', 'b', 'c', 'd', 'e'] },
mounted () {
setTimeout(() => {
this.items.splice(2, 0, 'f')
}, 2000);
}
});
</script>
</body>
</html>
上面過(guò)程的圖畫重現(xiàn)
插入過(guò)程.jpg
如果不使用key,則每一項(xiàng)都需要強(qiáng)制更新弟断,在創(chuàng)建最后一項(xiàng)
不使用key過(guò)程.jpg
若使用key循環(huán)舊數(shù)組多搀,當(dāng)發(fā)現(xiàn)舊開(kāi)始節(jié)點(diǎn)與新開(kāi)始節(jié)點(diǎn)的key不相等時(shí),patch舊節(jié)點(diǎn)與新節(jié)點(diǎn)最后一項(xiàng)喜鼓,過(guò)程如下
1际乘、patch A
舊數(shù)組:a b c d e
新數(shù)組:a b f c d e
2坡倔、patch B
舊數(shù)組:b c d e
新數(shù)組:b f c d e
3、patch E
舊數(shù)組:c d e
新數(shù)組:f c d e
4脖含、patch D
舊數(shù)組:c d
新數(shù)組:f c d
5罪塔、patch C
舊數(shù)組:a b c d e
新數(shù)組:a b f c d e
6、舊節(jié)點(diǎn)全部處理完畢养葵,新節(jié)點(diǎn)只剩下f征堪,就會(huì)把f插入到c前面即可。
不使用key和使用Key比較关拒,前者是更新C->F佃蚜、D->C、 E->D三次着绊,插入E;后者是只進(jìn)行了插入F的操作谐算,在數(shù)據(jù)量大的時(shí)候,性能優(yōu)化的效果顯而易見(jiàn)畔柔。
結(jié)論
1氯夷、key的作用是為了高效更新虛擬DOM,原理是在源碼patch.js的patchVnode過(guò)程中靶擦,會(huì)觸發(fā)updateChildren()方法中可以通過(guò)key精準(zhǔn)判斷節(jié)點(diǎn)是否是同一節(jié)點(diǎn)腮考,從而避免頻繁更新不同元素,使得整個(gè)patch過(guò)程更加高效玄捕,減少DOM操作量踩蔚,提高性能。
- 另外枚粘,若不設(shè)置key還可能在列表更新時(shí)引發(fā)一些隱蔽的bug
- vue中在使用相同標(biāo)簽名元素的過(guò)渡切換時(shí)馅闽,也會(huì)使用到key屬性,其目的也是為了讓vue可以區(qū)分它們,否則vue只會(huì)替換其內(nèi)部屬性而不會(huì)觸發(fā)過(guò)渡效果福也。