看完了这节,但是还是没明白为何v-for一定需要key并且还不能是index,都是理论,能不能贴出源码证明啊

来源:4-9 虚拟DOM-diff算法概述

慕丝7210068

2020-05-29

写回答

2回答

双越

2020-05-30

关于 index 作为 key 的解释。

例如,旧的 dom 结构是这样的

<ul>
    <li key="0">张三</li>
    <li key="1">李四</li>
    <li key="2">王五</li>
</ul>

新的 dom 结构是这样的

<ul>
    <li key="0">李四</li>
    <li key="1">张三</li>
    <li key="2">王五</li>
</ul>

这种情况,如果拿  tag 和 key 作为标准来对比,那就出错了,张三和李四就无法互换位置了。

正确的 key 应该不能拿 index ,而是用一个唯一的 id 或者标识,如:

<ul>
    <li key="zhangsan">张三</li>
    <li key="lisi">李四</li>
    <li key="wangwu">王五</li>
</ul>

这种 key ,顺序变了也没关系。

1
0

双越

2020-05-29

源码中有通过 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 时都有很常见的应用场景,先理解了这个道理,再去有目的的看源码。

我们看源码不是做侦探,什么都不知道就试着从源码找到答案。相反,我们看源码是做解剖,实现知道了结果,然后扒开来看看。

0
2
慕粉3871079
回复
慕丝7210068
开始index == 0 可能对应是张三,后面变了之后可能index == 0 就成了李四了,那其实内容没变,只是位置变了,那这个index就毫无意义啊。如果把index换成有意义的id,是否会减少很多渲染呢?
2021-02-20
共2条回复

2024版 前端框架及项目面试 聚焦Vue3/React/Webpack

面向1-3年前端的框架及项目面试“刚需内容”

4664 学习 · 1644 问题

查看课程