首先我们在vue心目中看到很多使用key值的运算,经常也逛逛各种论坛,有人提出增加key值会减少vue的性能,(vue有就地复用原则是增强浏览器运行性能的),那么问题来了,为啥要“多此一举”了?下面是我个人的一些看法: diff算法是为啥增加key的核心,diff算法说白了就是我们在数据结构里面的差异查找算法,下面贴一段vue的部分代码: if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx) } if(isDef(newStartVnode.key)) { // map 方式获取 idxInOld = oldKeyToIdx[newStartVnode.key] } else { // 遍历方式获取 idxInOld = findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx) } 创建map函数
function createKeyToOldIdx (children, beginIdx, endIdx) { let i, key const map = {} for (i = beginIdx; i <= endIdx; ++i) { key = children[i].key if (isDef(key)) map[key] = i } return map } 遍历寻找
// sameVnode 是对比新旧节点是否相同的函数 function findIdxInOld (node, oldCh, start, end) { for (let i = start; i < end; i++) { const c = oldCh[i]
if (isDef(c) && sameVnode(node, c)) return i
}
} 我们可以看到在vue中首先会查询是否有key如果没有会采用遍历的方式查找vnode和oldvnode的差别,生成补丁对象,如何通过patch方法,更新dom节点,vue利用key的唯一性,产生map对象,避免就地复用情况,相比于遍历map映射当然比较快;