v-for中的key
说到这个问题想必要举个例子了
image
没有key
当选中吕不为时,添加楠楠后选中的确是李斯,并不是我们想要的结果,我们想要的是当添加楠楠后,一种选中的是吕不为
有key
同样当选中吕不为时,添加楠楠后依旧选中的是吕不为。
可以简单的这样理解:加了key(一定要具有唯一性) id的checkbox跟内容进行了一个关联。是我们想达到的效果
查过相关文档,图例说明很清晰。
vue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设
首先讲一下diff算法的处理方法,对操作前后的dom树同一层的节点进行对比,一层一层对比,如下图:
before.png
当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。
比如一下这个情况:
我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
vue中列表循环需加:key="唯一标识" 唯一标识可以是item里面id index等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM
使用v-for
更新已渲染的元素列表时,默认用就地复用
策略;列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素;
我们在使用的使用经常会使用index
(即数组的下标)来作为key
,但其实这是不推荐的一种使用方法;
举个🌰
上面这种是我们做项目中常用到的一种场景,因为不加key,vue现在直接报错,所以我使用index作为key;下面列举两种常见的数据更新情况
1.在最后一条数据后再加一条数据
此时前三条数据直接复用之前的,新渲染最后一条数据,此时用index
作为key
,没有任何问题;
2.在中间插入一条数据
此时更新渲染数据,通过index
定义的key
去进行前后数据的对比,发现
通过上面清晰的对比,发现除了第一个数据可以复用之前的之外,另外三条数据都需要重新渲染;
是不是很惊奇,我明明只是插入了一条数据,怎么三条数据都要重新渲染?而我想要的只是新增的那一条数据新渲染出来就行了
最好的办法是使用数组中不会变化的那一项作为key
值,对应到项目中,即每条数据都有一个唯一的id
,来标识这条数据的唯一性;使用id
作为key
值,我们再来对比一下向中间插入一条数据,此时会怎么去渲染
现在对比发现只有一条数据变化了,就是id
为4的那条数据,因此只要新渲染这一条数据就可以了,其他都是就复用之前的;
同理在react中使用map渲染列表时,也是必须加key,且推荐做法也是使用id
,也是这个原因;
所以一句话,key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
微信公众号: 我的web前端自救之路
回复 加群 ,跟大佬们一起交流技术吧
