v-for中为什么要用key

54 篇文章 4 订阅

一、v-for中为什么要用key

  1. vue中列表循环需加:key=“唯一标识” 唯一标识尽量是item里面id等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM。

  2. key主要用来做dom diff算法用的,diff算法是同级比较,比较当前标签上的key还有它当前的标签名,如果key和标签名都一样时只是做了一个移动的操作,不会重新创建元素和删除元素。

  3. 没有key的时候默认使用的是“就地复用”策略。如果数据项的顺序被改变,Vue不是移动Dom元素来匹配数据项的改变,而是简单复用原来位置的每个元素。如果删除第一个元素,在进行比较时发现标签一样值不一样时,就会复用之前的位置,将新值直接放到该位置,以此类推,最后多出一个就会把最后一个删除掉。

  4. 尽量不要使用索引值index作key值,一定要用唯一标识的值,如id等。因为若用数组索引index为key,当向数组中指定位置插入一个新元素后,因为这时候会重新更新index索引,对应着后面的虚拟DOM的key值全部更新了,这个时候还是会做不必要的更新,就像没有加key一样,因此index虽然能够解决key不冲突的问题,但是并不能解决复用的情况。如果是静态数据,用索引号index做key值是没有问题的。

  5. 标签名一样,key一样这时候就会就地复用,如果标签名不一样,key一样不会复用。

二、举几个例子来说明一下

  1. 在无key值的情况下
<ul>
  <li v-for="(item, index) in lists">
    <input type="checkbox" :value="item.text"/>
    {{item.text}}
  </li>
</ul>
 
 
<script>
  var vm = new Vue({
  el: '#app',
  data: {
    lists: [
      { id: 1, text: '张' },
      { id: 2, text: '吕' },
      { id: 3, text: '王' }
    ]
  },
  methods: {
    remove() {
      //注意这里是shift
      this.lists.shift()
    }
  }
 })
</script>

(1)选中第一个节点的复选框,点击删除,vue中是这样操作的,删除后新的数据是吕和王,这时会进行比较,第一个节点的标签一样,值不一样,就会复用原来位置的标签,不会做删除和创建,直接将吕赋值张,第一个节点就显示吕了,但是没有删除,在第一个节点中是将复选框选中的,当我们看见好像是把第一个删除了,但是点击后去看复选框的时候还是选中在第一个,如果是直接将第一个节点删除了那么复选框就不会选中,看下图为操作后的效果:

删除前:
删除后:
(2)我们在选中最后一个节点的复选框(王前面的复选框),点击删除,这时候删除完会发现没有被选中的了,我们点击删除时,删除的是第一个数据,但dom中其实是删除的最后一个节点,因为在最后一个节点中的复选框是选中的,但被删除掉了,所以删除完没有选中的复选框了。
删除前:
删除后:
总结:当我们选择了第一个第一个多选框,点击删除做删除第一个节点操作,vue中会做两个节点比较,这时候发现标签一样,就会复用原来的位置,将新的节点覆盖到这个位置上,知道最后旧的oldNode多了一项,这时就会删除多余的这一个节点,最后实际上删除的就是最后一个节点。
  1. 将index做为key
<ul>
  <li v-for="(item, index) in lists" :key="index">
    <input type="checkbox" :value="item.text"/>
    {{item.text}}
  </li>
</ul>

删除前的index是0 1 2,删除后的index是0 1,这时候还会进行复用,因为复用的策略是根据一个唯一标识,不管怎么删这个索引都是会更新到有序的01…,最后key并没有起到作用,所以为了防止这样必须要使用一个唯一的标识来做为key。

  1. 使用数据中id做为key
<ul>
  <li v-for="(item, index) in lists" :key="item.id">
    <input type="checkbox" :value="item.text"/>
    {{item.text}}
  </li>
</ul>

同上面操作,还是选中第一个节点的复选框,删除前的key是1 2 3,因为删除的是第一个数据,所以删除后的key就是2 3,这时候就会知道2和3是需要复用的,1是被删除掉的,这时候就会根据key找的对应节点做移动,最后删除没有找到key的元素,这时候就正确了。

删除前:
删除后:
(2)我们在选中最后一个节点的复选框(王前面的复选框),点击删除,这时候删除完会发现没有被选中的了,我们点击删除时,删除的是第一个数据,但dom中其实是删除的最后一个节点,因为在最后一个节点中的复选框是选中的,但被删除掉了,所以删除完没有选中的复选框了。
删除前:
删除后:
选中最后一个节点,点击删除
删除前:
删除后:
做添加也是同样的操作,没有key会在最后增加一个新的dom,并不是在最开始的dom前做的新增。

三、画图说明

在这里插入图片描述
在无key的情况下,我们可以看到是修改了四次dom,在有key的情况下,只需移动删除,不需要去修改dom,所以我们在使用v-for写上key,防止一会修改数据的时候,出现bug。

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

归途风景111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值