<!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>
// 创建实例
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>
上面过程的图画重现
如果不使用key,则每一项都需要强制更新,在创建最后一项
若使用key循环旧数组,当发现旧开始节点与新开始节点的key不相等时,patch旧节点与新节点最后一项,过程如下
1、patch A
旧数组:a b c d e
新数组:a b f c d e
2、patch B
旧数组:b c d e
新数组:b f c d e
3、patch E
旧数组:c d e
新数组:f c d e
4、patch D
旧数组:c d
新数组:f c d
5、patch C
旧数组:a b c d e
新数组:a b f c d e
6、旧节点全部处理完毕,新节点只剩下f,就会把f插入到c前面即可。
不使用key和使用Key比较,前者是更新C->F、D->C、 E->D三次,插入E;后者是只进行了插入F的操作,在数据量大的时候,性能优化的效果显而易见。
结论
1、key的作用是为了高效更新虚拟DOM,原理是在源码patch.js的patchVnode过程中,会触发updateChildren()方法中可以通过key精准判断节点是否是同一节点,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
- 另外,若不设置key还可能在列表更新时引发一些隐蔽的bug
- vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。