key的作用,就是用来判断列表更新前后key是否相同,相同时,新节点直接复用旧节点,无需创建新节,优化性能
讨论一下以下几种情况,帮助理解为什么加key,为什么不用index做key
- 不加key
- 用随机数
- 用数组索引 index (重要)
- 用数组元素唯一属性,如id
讨论前我们先看一下vue对于是否为sameVnode的判断逻辑,这里我们关注a.key===b.key就可以了 ,至于更详细的diff过程可以看看这篇详解vue diff
1.不加key
显然,不加key,key就为undefined,undefined====undefined显然为true,数组每一项都直接复用旧的,高效。
vue官方文档也有这么一句话
然而如果数组有变动,就会复用出错,所以不加key时,vue默认聪明的你知道数组不会变,故意不加,而不是忘记了加
2.用随机数
前后key都是随机数,显然不会出现相等的情况(如果有,请去买彩票),那么就不存在复用,也就是删除所有旧元素,创建所有新元素,这显然是暴力低效的
其实说不能用随机数做key不太准确,准确的说,不能用 :key='Math.random()'这种写法,如果你生成数组的时候就让id为一个随机数,好像未尝不可,算是一条退路吧。
3.用数组索引 index
分两种情况 :1.有状态 2. 无状态 。
有状态是指数组元素可能添加,删除,移动,无状态反之。
有状态:(重点)
假设有数组[A,B,C],用index做key,则对应key为0,1,2。
删除B,变为[A,C],对应key为0,1。
显然,删除前 B 的key为1,删除后 C 的key为1,
那么根据sameVNode复用原则,复用相同key的元素,故C直接复用B就可以了,显然复用出错
无状态:数组没有变化,每一项key比较下来都相同,直接复用,高效,这其实跟不加key差不多。
4.用数组元素唯一属性,如id
显然,用唯一id是为了保证高效更新,同时也保证准确复用