请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

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

正在回答 回答被采纳积分+3

2回答

双越 2020-05-30 13:07:24

关于 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 回复 有任何疑惑可以回复我~
双越 2020-05-29 22:57:16

源码中有通过 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 回复 有任何疑惑可以回复我~
  • 提问者 慕丝7210068 #1
    后半部分index那里还是没有看懂,为什么index就是不行
    回复 有任何疑惑可以回复我~ 2020-05-29 23:06:55
  • 慕粉3871079 回复 提问者 慕丝7210068 #2
    开始index == 0 可能对应是张三,后面变了之后可能index == 0 就成了李四了,那其实内容没变,只是位置变了,那这个index就毫无意义啊。如果把index换成有意义的id,是否会减少很多渲染呢?
    回复 有任何疑惑可以回复我~ 2021-02-20 17:09:46
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信