- 这种就直接上源码就好(Vue.js v2.7.4)
...略...
if (isTrue(children._isVList) &&
isDef(c.tag) &&
isUndef(c.key) &&
isDef(nestedIndex)) {
c.key = "__vlist".concat(nestedIndex, "_").concat(i, "__");
}
...略...
- 如果在v-for时key未定义. vue中给的是一个拼接字符串, 确实给这个拼接字符串和指定index是一样的效果, 但是很多文章直接说默认是index就是不严谨的
- V3官方文档描述如下 V2也有类似描述
在没有 key 的情况下,Vue 将使用一种最小化元素移动的算法,并尽可能地就地更新/复用相同类型的元素。
- 什么是就地更新复用, 新旧虚拟dom对比的时候是一样的操作(只有一个diff算法), 旧首新首, 尾尾, 首尾, 尾首 去diff对比新旧虚拟dom, 那么index作为key的情况是不是就是一种原地复用的情况, 因为key就是index, 就是和数组元素的顺序一样, 是不是index作为key的diff算法对比过程永远不需要移动dom只需要做 增加/删除 操作, 例如在数组头插入一个元素, 该vnode的key为0, 假设原数组不为空, 那么是不是复用了原数组的第一个key为0的oldnode, 那么真实dom自然不需要移动, 对比过程在旧首新首的时候就能成功命中key相等的vnode, 在进行增加删除的操作前永远只需要旧首新首对比一次就能命中 对比到最后, 新增最后一个节点即可. 这样就实现了就地更新/复用相同类型的元素
- 结论
官方文档的这句话就是给你解释了一下源码. 学习不是一个道听途说, 人云亦云的过程, 而是一个谨小慎微, 抽丝剥茧的过程