16_Vue列表渲染中key的工作原理和虚拟DOM对比算法
1|0key的作用
- 粗略的讲,key的作用就是给 节点 设置一个 唯一的标识
- 就像我们人类社会中,每个人的身份证号一样
- 在大部分对key要求不是很严格的场景下,使用index作为key是没问题的
- 但是我们本章要探讨的是,其他情况,可能会出现问题的情况
来看个例子
1|1案例
我现在提一个需求
1|2需求
- 我添加一个按钮,这个按钮会给我添加一个 老刘 这个对象(老六)
- 这个老刘呢,不能添加在 persons数组的最后面,要在最前面
- 不然看不出问题
click方法只调用一次哈,多了不好分析,这里使用的是事件修饰符
1|3测试
感觉没什么问题呀,为什么会讲这个呢
警告,错误没有,页面显示正常,也没有报错
有问题吗,有,这里面有个很严重的问题
2|0增加需求
再来测试下
没问题啊,咋地?来,我给你演示下
2|1问题出现
- 我在添加老刘之前,我先给张三李四王五的input框框中,输入一些文字
- 然后添加老刘,我们来看看这次是什么样子的
测试
- 我们希望看到的是什么? == 老刘出现的时候,是一个空白的input框
- 但现在问题是什么?下方的三个兄弟的信息 分别错位了 为什么会这样
- 那看看 现在我将 :key换成 item.id会怎么样
再测试
哦~那我们现在可以总结一个情况
- 使用index会出现这个问题
- 但是使用自带的id就没这个问题,这是我们现在所遇到的情况
3|0key的工作原理和对比算法
这里使用流程图讲解
3|1分析index作为key
初始化流程
1、一切的一切都是你写了这段代码
2、vue是不是会拿着你的数据生成 虚拟DOM?(并不是一开始就把数据给你变为页面DOM的,是有流程的)
3、真实DOM上是没有这个key的,虚拟DOM上必须要有(没有,vue不能高效工作)
4、上图这个是已经生成真实DOM了,我们现在还处于虚拟DOM生成的过程中(假设现在页面还没有生成这三个li标签)。现在,在内存当中是不是有这三个虚拟DOM了(3个li标签)
5、将虚拟DOM转换为真实DOM
6、请问,用户是在哪里操作的数据?虚拟DOM还是真实DOM,用户输入的数据,残留在谁身上了?虚拟还是真实DOM?(用户操作的全是真实DOM)
这个时候初始化流程就结束了
数据更新,老刘出现
1、新的数据出现了,老刘出现了,老刘是排在所有人的前面
2、随后,会根据新的数据,生成新虚拟DOM(因为数据发生改变了)
这个时候,老刘的key就是0了,因为你使用index作为索引,老刘排在最前面(因为我们插在最前面)
重点来了:,在目前的整个流程当中,生成了两份虚拟DOM,vue不会根据上面这个修改后的虚拟DOM进行真实DOM的创建,而是会将两个虚拟DOM进行一个对比算法,这就是该算法的由来
3|2虚拟DOM的对比算法
对比的时候,依赖着这个key,怎么对比的呢?请让我用文字来为你形容
- 首先,它来到这个新的虚拟DOM当中,按照顺序,先取出第一个(老刘)
- 接下来,它来到旧的虚拟DOM中,寻找和 老刘拥有相同key值的人 谁呢? 张三吖
- 怎么对比的呢?
- 这里先暂停下,我来问个问题?请问,对比二者的input的时候,它们input的内容是否相等?
- 刚刚对比不一样(老刘-30与张三-18)的怎么办,一样的(input)怎么办呢?
- 一样的结果就是 复用
- 什么是复用呢?
- 要不你看这样吧,你这个张三的虚拟DOM一定转换过真实DOM(都用对比算法了肯定转换过)
- 你看昂,张三的input转换过真实DOM,那么我老刘的input与张三的input是一样的(虚拟DOM中)
- 也就出现了下面的情况
- 然鹅,张三的真是input当中,还残留着用户的输入
- 那么,搬用过来的时候,把残留输入一起带过来了
- 错在哪里
- 使用index作为key,导致了 复用 的发生,顺序乱了
- 由于这个细节错误的出现,导致了错位的生成
- 以此类推,到王五的时候,key = 3在旧的虚拟DOM当中不存在,那么只有自己生成了
我们出现这个错误的原因是执行了这个奇葩的需求,但是通过这个需求,我们能对key进行更加深入的理解
3|3为什么说效率低
- 我们来看图,图里解释的很清楚了
- 二者的input是相等的,在虚拟DOM当中
- 但是二者的 插值语法这个位置
- 是不相等的,不相等,那么就没有办法采用 复用行为
- 没有办法采用复用行为,那么 插值语法这里的真实DOM就需要自己生成
- 也就是这一块,是新的虚拟DOM转换为真实DOM自己生成的
3|4分析item.id作为key
通过上面的分析,这里思路就很清晰了
- 还是一样的,因为这些初始化数据,我们在内存当中生成了虚拟DOM
- 虚拟DOM转换为真实DOM
- 用户在真实DOM进行操作,残留了输入
- 接下来我们添加了一个成员,老刘
- 那么虚拟DOM被更新了
- 更新了,那么就会和旧的虚拟DOM进行对比
- 所以使用id作为key是不会出现刚刚那个问题的
- 效率高吗,高,因为服用了,错位了吗,没有
3|5不写key
- 如果你不写key,那么vue在遍历的时候会默认将索引值index作为key
- 既然index作为key了,这个DOM身上是有key的,那么自然不会报错
- 既然index作为key了,遇见刚刚那个问题自然会出现问题
4|0面试题
4|1react、vue中的key有什么作用?
分为如下几步回答
虚拟DOM中key 的作用
虚拟DOM对比算法(为了复用节点)
用index作为key可能会引发的问题
开发中如何选择key
__EOF__

本文链接:https://www.cnblogs.com/wavesbright/p/16836562.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本