vue中使用v-for时为什么不能用index作为key

2022-02-25  本文已影响0人  扶得一人醉如苏沐晨

https://www.cnblogs.com/youhong/p/11327062.html

必须要用key,而且不能用index和random,

key是vue中vnodef的唯一标记,通过这个key,我们的df操作可以更准确,更快速

在diff算法中用tag和key来判断,是否是sameNode

可以减少渲染次数,提高渲染性能

要理解diff的过程,先要对virtual dom有个了解,这里简单介绍下。

我们都知道重绘和回流,回流会导致dom重新渲染,比较耗性能;而virtual dom就是用一个对象去代替dom对象,当有多次更新dom的动作时,不会立即更新dom,而是将变化保存到一个对象中,最终一次性将改变渲染出来。


diff原理

比较过程可以理解为一个层层递进的过程,每一级都是一个vnode数组,当比较其中一个vnode时,若children不一样,就会进入updateChildren函数,然后逐一比较children里的节点,对于children的children,再循环以上步骤。

在diff算法中用tag和key来判断,是否是sameNode

当不加key时,key都是undefined,默认相同,diff算法就会就地复用来进行比较

B复用A的结构,C复用B的结构,D复用C的结构,E复用D的结构,删除E;然后如果数据有变化,再更新数据


如果加上唯一识别的key(1,2,3,4,5)


以上,B、C、D、E全部可以复用,删除A即可从以上的对比可以看出,加上key可以最大化的利用节点,减少性能消耗


为什么不建议用index作为key

1)index作为key,其实就等于不加key

2)index作为key,只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出(这是vue官网的说明)

虽然加上了key,但key是就是当前的顺序索引值,此时sameNode(A,B)依然是为true,所以与不加key时一样,A复用B的结构并将数据更新为B。下面以一个demo来说明。

当我们删除一个对象数组的某一条对象后,数组动态改变,index也会改变,diff依然会采取就地复用的原则

总结

diff算法默认使用“就地复用”的策略,是一个首尾交叉对比的过程。

用index作为key和不加key是一样的,都采用“就地复用”的策略

“就地复用”的策略,只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

将与元素唯一对应的值作为key,可以最大化利用dom节点,提升性能












如果此时 list 的 item 是 select 的选项,其中 Person3 是选中的,这个时候 Person2 被删除了,用 index 作为 key 就会变成是 Person4 选中的了,这就产生了bug。

上一篇下一篇

猜你喜欢

热点阅读