简介:我们通常会看到,在使用v-for的时候,一般会提供一个唯一的key值,为什么要使用key值呢?
vue官方文档上给出:
当Vue.js用v-for正在更新已经渲染过的元素列表时,会默认“就地复用”策略。
即如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是简单的复用此处的每个元素,并确保在特定索引下显示已经被渲染过的每个元素。
虽然这个模式是高效的,但是只适用于不依赖子组件和临时DOM状态的列表渲染输出(例如表单输入值)
我们通常会使用给一个唯一的key值,来给vue一个提示,以便==它能跟踪每个节点的身份==,从而重新更新和排序现有元素。
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
1
2
3
2
3
如果要介绍key的用法,不得不先介绍下虚拟DOM的Diff算法了。
我们知道,vue和react都实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只需要操作数据,就可以重新渲染页面,而隐藏背后的原理就是虚拟DOM的Diff算法。
# diff算法有两个核心
当页面数据发生变化时,Diff算法只会比较同一层级的节点:
- 如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了。
- 如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。
如下图所示
当某一层有很多相同的节点时(列表节点),Diff算法更新的过程遵循以上规则。
下面我们来看下这个情况
我们希望B和C直接加一个F节点,Diff算法执行起来又是怎样的呢,看下图
从图中我们可以看出C更新为F,D->C,E->D,最后再插入E,是不是看起来很繁琐?
因此我们需要使用key来给每个节点增加一个唯一性标识,Diff算法就可以正确的找到此节点,找到正确的位置区插入该节点。
总结
# key的作用就是高效的更新虚拟DOM。
另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,
否则vue只会替换其内部属性而不会触发过渡效果。(比如输入框)