Advertisement

写React/Vue项目时为什么要在列表组中写key,其作用是什么?

阅读量:

首先了解一下虚拟dom和diff算法

  • 虚拟dom:用一个简单的对象去替代复杂的dom对象,该对象存储了对应dom的一些重要参数,在改变dom之前,会先比较相应的虚拟dom,如果需要改变,才会将相应的改变应用到真实dom上
  • diff算法(差异算法):用新渲染的对象树和旧的树进行对比,记录这两颗树的差异,记录下来的不同就是我们需要对页面正真的dom操作,然后把他们应用到正真的dom操作中,进行页面的变更;虽然每次视图结构都是整个全新的渲染,但是最后操作的只是dom不同的地方

写key的作用相当于给每一个vnode绑定一个id,可以根据这个key,更准确,更快 的拿到oldVNode对应的VNode(diff算法中比较的对象)

  • 更准确:带key就不是就地复用,在sameNode函数 a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。
  • 更快:利用key的唯一性生成map对象来获取对应节点,比遍历方式更快。

其实我们在正真写循环的时候,有时候不写key也不会出现什么问题,页面也会正常的渲染,我们的一些操作也能正确的得到相应,只是会跳出警告让你加上key,有时候我们为了省事直接让key = index,其实这些做法都是有一定的弊端的;

在一些情况下,不加key的速度会比加上key的速度更快,但是这并不是不加key的作用,而实没有key的情况下对节点的就地复用,可能提高性能;所谓的就地复用是不加key的一种渲染机制,因为没有key,就没有一个对象的一个标识,如果对里面内容进行调换位置,只是用需要修改的内容去替换已有的内容,增加也是相当于在最后多添加了一个对象;但是如果拥有了key,那么已经渲染的内容就相当于拥有了一个id,如果是调换位置,那么不回去修改内容,而是实现真正的去改变对应的位置

为了更好理解就地复用,可以这样想象,相当于每个人都有一个个座位,但是这些座位是没有名字的,谁都可以使用,今天可以我坐一号,明天别人也可以坐一号;而加上key,就相当于给这些座位写了每个人的名字,每个人每次都是坐自己的,如果某个人走了,顺带着自己的位置也走了,不会应该又来了一个人把这个位置分给他。

不加key的副作用:可能不会产生过度效果,或者在某些绑定节点数据(表单)状态,会出现错位,Vue的文档也声明了,”这个默认的模式是搞笑的,但是只适用于不依赖子组件状态或临时dom状态(如:表单输入值)的列表渲染输出“

有时习惯使用key = index,这样做虽然给了一个key,但是如果删除某个内容,重新渲染之后,删除中间的任意一项(假如由三项,删除2),index会从123 ----> 12,而不是期待的由123 ----> 13,如果只为渲染可以使用

所以尽量在列表组中写key,不仅可以避免一些莫名的bug,也可以提高代码规范

可以看看前两个回答Vue2.0 v-for 中 :key 到底有什么用?

全部评论 (0)

还没有任何评论哟~