这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战
前言
Vue中key的作用是什么?这个问题大家应该都不陌生。当然,我也接触过,但是还停留在接触这个阶段,当真正遇到问题的时候,差点栽跟头。
我遇到的问题
近几天,有一个表格表头拖拽的需求,如图所示,右侧自定义列的字段是表格中正展示的字段,右侧自定义列中的字段可拖拽,同时在左侧的表格中同步拖拽后的顺序。自身在实践的过程中发现,右侧拖拽后,左侧表格中的显示有问题,比如标题和创建时间位置互换,但是表格中渲染出来的第一列表头是标题,第二列还是标题,下面对应的内容是对的,那这个问题的原因是什么呢?先来看看我的代码实现吧。
表格拖拽代码
表格代码:
自定义列拖拽组件封装代码:
其实当时我在排查的时候,首先在组件中排查,以为拖拽有问题,但是实际上,内容是对的,只是表头有问题,这才想起之前的一个知识点,说实话,这个点早就知道,但是自己也确实没遇到过类似问题,所以也没在意。一般我在写for循环的时候,都会像上述代码中那样写,key值就写个index,一直没遇到过问题。哈哈。
key的真实作用
key是虚拟DOM对象的标识,当数据发生变化时,vue会根据新数据生成新的虚拟DOM,随后VUe进行新虚拟DOM与旧虚拟DOM的差异比较。比较规则是什么呢?
(1)旧虚拟DOM中找到了与新虚拟DOM相同的key: 若虚拟DOM中内容没变,直接使用之前的真实DOM;若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2)旧虚拟DOM中未找到与新虚拟DOM相同的key,则创建新的真实DOM,随后渲染到页面中。
问题解决
那上面我的问题就应该有答案了。我是用index值作为的key,那当我拖拽之后,在进行对比的过程中,发现索引值没变,那干脆内容也不变了。后来我将key值加index的同时,还加上了一个会变化的字段,那就是列的定义字段,这样就能保证在进行diff算法的过程中,会有变化啦。
总结
在日常开发中个,尽量选择每条数据的唯一标识作为key,比如id等,避免出现类似问题;如果不对数据的逆序添加、删除等破坏顺序的操作,仅仅用于列表渲染,其实使用index作为key是没有问题的。
Happy Ending.