加上key的重要性

来源:5-9 组件更新(3)

慕粉6407827

2020-07-01

都说加上key是为了加快diff的速度。我在源码中看到key的作用有两个地方,一个是sameVnode()方法,

function sameVnode (a, b) {
  return (
    a.key === b.key && (
      (
        a.tag === b.tag &&
        a.isComment === b.isComment &&
        isDef(a.data) === isDef(b.data) &&
        sameInputType(a, b)
      ) || (
        isTrue(a.isAsyncPlaceholder) &&
        a.asyncFactory === b.asyncFactory &&
        isUndef(b.asyncFactory.error)
      )
    )
  )
}

但是这个方法中的key如果如果都没有,那就是 undefined === undefined,结果仍然是true的,如果两个不带key的 div 标签进行比较,那么vue仍然判断这两个是相同的vnode。
也会走patchVnode() 方法。
还有一个地方使用了key,

if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
        idxInOld = isDef(newStartVnode.key)
          ? oldKeyToIdx[newStartVnode.key]
          : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)

这里是可以看得出如果vnode带上key的话,直接从oldch数组中拿对应key的元素。没带key的话则需要一个一个地去找。这里确实体现出里带上key的好处。但是如果是简单的结构两种处理的方法速度也差不多吧。

所以我不是很明白,为什么说加上key会提高diff的速度,到底能提高多少速度呢???麻烦老师不吝赐教一下,感谢!!!

写回答

1回答

ustbhuangyi

2020-07-01

加 key 主要不是为了性能,而是为了区分 2 个 vnode 的节点,比如一个列表,你删除其中一项,如果不加 key 区分,那么删除后新旧 vnode 对比就会出现 bug,因为列表元素 DOM 结构相同,Vue 会把原本不同的两个节点认为是 sameVnode,导致 bug。

2
3
慕粉6407827
非常感谢!
2020-07-06
共3条回复

Vue.js 源码深入解析 深入理解Vue实现原理

全方位讲解 Vue.js 源码,进阶高级工程师

4984 学习 · 1037 问题

查看课程