当前位置:   article > 正文

Vue:v-for中为什么要使用key_vue for循环后边为什么要写key

vue for循环后边为什么要写key

想要知道为什么使用key,首先要了解key是什么

官网是这么说的:
为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的 key attribute:

通俗讲: v-for中的key来给每个节点做一个唯一的标识,diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点;key的主要作用是为了高效的更新虚拟dom,另外vue在使用相同标签名元素的过渡切换时,也会使用到key属性,目的是让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

了解了key之后, 再来说说为什么要使用key

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

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

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

举个例子

在没有key的时候

    <template>
      <div class="about">
        <ul>
          <li v-for="(item, index) in cityLists">
            <input type="checkbox" :value="item.city" />
            {{ item.city }}
          </li>
          <button @click="remove">删除</button>
        </ul>
      </div>
    </template>

    <script>
    export default {
      data() {
        return {
          cityLists: [
            { id: 1, city: "天津" },
            { id: 2, city: "长沙" },
            { id: 3, city: "郑州" },
          ],
        };
      },
      methods: {
        remove() {
          //注意这里是shift
          this.cityLists.shift();
        },
      },
    };
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

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

(2)我们在选中最后一个节点的复选框(郑州前面的复选框),点击删除,这时候删除完会发现没有被选中的了,我们点击删除时,删除的是第一个数据,但dom中其实是删除的最后一个节点,因为在最后一个节点中的复选框是选中的,但被删除掉了,所以删除完没有选中的复选框了。看下图为删除前后的效果对比:

总结: 当我们选择了第一个第一个多选框,点击删除做删除第一个节点操作,vue中会做两个节点比较,这时候发现标签一样,就会复用原来的位置,将新的节点覆盖到这个位置上,知道最后旧的oldNode多了一项,这时就会删除多余的这一个节点,最后实际上删除的就是最后一个节点。

将index做为key

    <ul>
      <li v-for="(item, index) in lists" :key="index">
        <input type="checkbox" :value="item.city" />
        {{ item.city }}
      </li>
      <button @click="remove">删除</button>
    </ul>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

将id做为key

    <ul>
      <li v-for="(item, index) in lists" :key="item.id">
        <input type="checkbox" :value="item.city" />
        {{ item.city }}
      </li>
      <button @click="remove">删除</button>
    </ul>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

选中最后一个节点,点击删除

做添加也是同样的操作,没有key会在最后增加一个新的dom,并不是在最开始的dom前做的新增。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/137903
推荐阅读
相关标签
  

闽ICP备14008679号