注册

v-for中diff算法

当没有key时

57fc75b5ae1f4a31b875459d3699b55a~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

获取新旧数组长度,取最短的数组(Math.min())进行比较,如果用长的数组进行比较,会发生越界错误

b3bc0281c616474483b9e113f58a8bbf~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

以短数组进行for循环,从新旧数组各组一个值进行patch,如果内容一样就不进行更新,如果内容不一样,Vue源码会进行更深层次的比较,如果类型都不一样的话,直接创建一个新类型,如果类型一样,值不同,就只更新值,效率会更高,当for循环完毕,新旧数组长度会进行比较,如果旧的长度大有新的长度,就会执行unmountChildren,删除多余的节点,如果新的长度大于旧的长度,就会执行mountChildren,创建新的节点

当有key时

8c1f4a2d23ad4ab0957403cd4eeb85d6~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

第一步,从头部开始遍历

15685bfd0ff04258994567152d9ab192~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

通过isSameVNodeType进行比较

882a16bcc67d49e5b5c46400b535b6c9~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

如果type 和 key 都一样,继续遍历,如果不同,跳出循环,进入第二步

第二步,从尾部开始遍历

37beec7abdf34a3db87e9d19e984f953~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

和第一步操作一致

如果不同,跳出循环进入第三步

第三步,果旧节点遍历完,依然有新的节点,就是添加节点操作,用一个null和新节点进行patch,n1为空值时,是添加

d3956fe7582241fe95b8230c9eb37a93~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

854fb780e75c4df39fb372283a0beacb~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

如果新节点遍历完了,旧节点还有就进入第四步

第四步,新节点遍历完毕,旧节点还有,就进行删除操作

03cc216c7f5348f6bb4734a802027fec~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?

第五步,如果是一个无序的节点,vue会从旧的节点里找到新的节点里相同的值并创建一个新的数组,根据key建立一个索引,找到了就放入新数组里,比较完之后,有多余的旧节点就删除,有没有比较过的新节点就添加


作者:啊哈呀呀呀呀
来源:juejin.cn/post/7100858461520560135

0 个评论

要回复文章请先登录注册