源码中有通过 key 来寻找新旧 vdom 里相同的节点,然后移动节点。就在 updateChildren 函数里。
理解这个问题,我觉得先不用一头扎进源码中,得先从逻辑上、道理上理解它为啥这么干。
例如 ul 里有 5 个 li ,很常见的 DOM 结构,对吧。基于这样的 DOM 结构,新旧 vnode 对比时,对比到子节点,即 5 个 li ,如果没有 key ,那我不知道这 5 个到第有没有变化,那只能把这 5 个全部销毁,然后全部重建。
如果我们规定一个 key 的机制,即同一层里,同样的 tag ,key 不变就表示该元素不会变。那在比较这 5 个 li 时,我就可以根据 key 来判断哪些没有变,没变的就可以不用销毁创建,这样就少了很多 DOM 操作。
但前提是 key 得是和 li 相对应的,如果 key 用了 index 。li 调整了顺序,这样通过 index 这个 key 来去做比较,那就会出现顺序上的错误,对吧。
上述的这些流程,在我们使用 vue 或者 React 时都有很常见的应用场景,先理解了这个道理,再去有目的的看源码。
我们看源码不是做侦探,什么都不知道就试着从源码找到答案。相反,我们看源码是做解剖,实现知道了结果,然后扒开来看看。