zoukankan      html  css  js  c++  java
  • v-for中的key

    使用v-for更新已渲染的元素列表时,列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改则重新渲染这一项,否则复用之前的元素。我们在使用的使用经常会使用index(即数组的下标)来作为key,但其实这是不推荐的一种使用方法,有时也可能出现问题,原因如下:

    在数组中插入一条数据:

    const list = [
        {
            id: 1,
            name: 'test1',
        },
        {
            id: 4,
            name: '我是插队的那条数据',
        }
        {
            id: 2,
            name: 'test2',
        },
        {
            id: 3,
            name: 'test3',
        },
    ]
    <div v-for="(item, index) in list" :key="index" >{{item.name}}</div>

    此时除了第一个数据可以复用之前的之外,另外三条数据都需要重新渲染,导致性能下降:

    之前的数据                                之后的数据
    
    key: 0  index: 0 name: test1     key: 0  index: 0 name: test1
    key: 1  index: 1 name: test2     key: 1  index: 1 name: 我是插队的那条数据
    key: 2  index: 2 name: test3     key: 2  index: 2 name: test2
                                     key: 3  index: 3 name: test3

    下面的例子是出现问题的:

    <div id="app">
        <div>
          <input type="text" v-model="name">
          <button @click="add">添加</button>
        </div>
        <ul>
          <li v-for="(item, index) in list" :key="index">   // v-for不添加key或者key赋值为索引都会有问题
            <input type="checkbox"> {{item.name}}
          </li>
        </ul>
    <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            name: '',
            newId: 3,
            list: [
              { id: 1, name: '李斯' },
              { id: 2, name: '吕不韦' },
              { id: 3, name: '嬴政' }
             ]
          },
          methods: {
            add() {
             //注意这里是unshift
              this.list.unshift({ id: ++this.newId, name: this.name })
              this.name = ''
            }
          }
        });
      </script>
      </div>

    当选中吕不为时,添加楠楠后选中的确是李斯,并不是我们想要的结果,我们想要的是当添加楠楠后,选中的还是吕不为

    加了具有唯一性的key的checkbox跟内容进行了一个关联,会达到我们想要的效果:

    <li v-for="(item, i) in list" :key="item.id">
        <input type="checkbox"> {{item.name}}
    </li>

    vue和react的虚拟DOM的Diff算法大致相同,首先看一下diff算法的处理方法,对操作前后的dom树同一层的节点进行对比,一层一层往下对比,如下图:

    比如下边这种情况,我们希望可以在B和C之间加一个F:

    Diff算法默认执行起来是这样的:

    即把C更新成F,D更新成C,E更新成D,最后再插入E,这样很没有效率。所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

    因为vue组件采用高度复用,增加Key可以标识组件的唯一性,这样是为了高效的更新虚拟DOM。同理在react中使用map渲染列表时,也是必须加key,且推荐做法也是使用id,也是这个原因。

    原文: https://www.jianshu.com/p/4bd5e745ce95

    https://segmentfault.com/a/1190000013810844?utm_source=tag-newest

  • 相关阅读:
    python基础(9):基本数据类型四(set集合)、基础数据类型补充、深浅拷贝
    python基础(8):基本数据类型三(dict)、is和==、编码和解码
    python基础(7):基本数据类型二(list、tuple)、range
    python基础(1):python介绍、python发展史
    python基础(6):基本数据类型一(int、bool、str)
    python基础(5):格式化输出、基本运算符、编码问题
    python基础(4):用户交互、if判断、while循环、break和continue
    python基础(2):python的安装、第一个python程序
    python基础(3):变量、常量、注释、基本数据类型
    java基础(32):类加载、反射
  • 原文地址:https://www.cnblogs.com/xjy20170907/p/11511723.html
Copyright © 2011-2022 走看看