v-for 要加key吗

327 阅读4分钟

Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key

运行出现迭代中的元素没有绑定key指令错误

我们先来聊聊

1、V-for的作用

将一个数组遍历或枚举一个对象属性的时候循环显示渲染页面

2、一定要加key吗?

对于用v-for渲染的列表数据来说,数据量可能一般很庞大,而且我们经常还要对这个数据进行一些增删改操作。假设我们给列表增加一条数据,整个列表都要重新渲染一遍,那不就很费事了。

3、而key的作用

  • 为了提高渲染性能。

当元素位置发生改变时 vue 不会对整个列表进行重新渲染,而只是更换一下 虚拟DOM 的顺序,这样可以减少资源消耗

4、index(即数组的下标)

写key时,我就统一的都把index索引作为key,然后接着开发,就像下面这样:

<h1 v-for="(item, index) in items" :key="index">{{ item.title }}</h1>

v-for默认是通过index索引来追踪变化,通过追踪index索引,Vue观测列表中的项目的顺序变化,并在顺序发生变化时,就地修改每个项目。

Vue文档中指出,“这个默认的index模式是高效的”,但是像Vue文档所说的那样,我们要尽可能使用数据的唯一ID来做每个元素的key,这样 Vue 可以更准确地追踪数组中项目的更改并更新组件状态,并且能够重用和重新排序现有组件,而不必重新渲染整个循环。

举个例子

  • 在数组后面追加一条数据
list = [
    {
        id: 1,
        num: '1'
    },
    {
        id: 2,
        num: 2
    },
    {
        id: 3,
        num: 3
    },
    {
        id: 4,
        num: '新增加的数据4'
    }
];

此时前三条数据页面不会重新渲染,直接复用之前的,只会新渲染最后一条数据,此时用index作为key,没有任何问题。

  • 在数组中间插入一条数据
list = [
    {
        id: 3, 
        num: 1
    },
    {
        id: 4, 
        num: '新增加的数据4'
    },
    {
        id: 2, 
        num: '2'
    },
    {
        id: 3, 
        num: '3'
    }
];

页面在去渲染数据的时候,通过index定义的key的比较,会有:

      之前的数据                    之后的数据

key: 0  index: 0 num: 1     key: 0  index: 0 num: 1
key: 1  index: 1 num: 2     key: 1  index: 1 num: '新增加的数据4'
key: 2  index: 2 num: 3     key: 2  index: 2 num: 2
                            key: 3  index: 3 num: 3

通过上面清晰的对比,发现除了第一个数据可以复用之前的之外,另外三条数据都需要重新渲染。

4.2、此时我们用id作为key值

list = [
    {
        id: 1,
        num: 1
    },
    {
        id: 4,
        num: '新增加的数据4'
    },
    {
        id: 2,
        num: 2
    },
    {
        id: 3,
        num: 3
    }
];
         之前的数据                               之后的数据

key: 1  id: 1  index: 0 num: 1     key: 1  id: 1  index: 0 num: 1
key: 2  id: 2  index: 1 num: 2     key: 4  id: 4  index: 1 num: '新增加的数据4'
key: 3  id: 3  index: 2 num: 3     key: 2  id: 2  index: 2 num: 2
                                   key: 3  id: 3  index: 3 num: 3

现在对比发现只有一条数据变化了,就是id为4的那条数据,因此只要新渲染这一条数据就可以了,其他都是就复用之前的。

key加索引index,id的作用

  • key属性可以避免数据混乱的情况出现。

推荐使用id

6、v-for渲染原理

  • 1.vue实现了一套虚拟DOM,使我们可以不直接操作DOM元素只操作数据,就可以重新渲染页面,而隐藏在背后的原理是高效的Diff算法

  • 2.当页面数据发生变化时,Diff算法只会比较同一层级的节点;

  • 3.如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点后面的子节点;如果节点类型相同,则会重新设置该节点属性,从而实现节点更新

  • 4.使用key给每个节点做一个唯一标识,Diff算法就可以正确失败此节点,"就地更新"找到正确的位置插入新的节点。

了解可以看看Diff详解

参考

参考