v-for 一定要绑定key值吗?为什么不建议使用index?

Posted 钧桐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了v-for 一定要绑定key值吗?为什么不建议使用index?相关的知识,希望对你有一定的参考价值。

写在前面

使用v-for更新已渲染的元素列表时,默认用就地复用策略;列表数据修改的时候,它会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素;
我们在使用的时候经常会用index来作为key,但其实这不是一个好习惯,面试这样说直接挂,讲真。

例子

const list = [
    {
        id: 1,
        name: 'test1',
    },
    {
        id: 2,
        name: 'test2',
    },
    {
        id: 3,
        name: 'test3',
    },
]
上面这种是我们做项目中常用到的一种场景,因为不加key,vue现在直接报错,所以我使用index作为key;下面列举两种常见的数据更新情况:

在最后一条数据后再加一条数据

const list = [
    {
        id: 1,
        name: 'test1',
    },
    {
        id: 2,
        name: 'test2',
    },
    {
        id: 3,
        name: 'test3',
    },
    {
        id: 4,
        name: '我是在最后添加的一条数据',
    },
]
此时前三条数据直接复用之前的,新渲染最后一条数据,此时用index作为key,没有任何问题;

在中间插入一条数据

const list = [
    {
        id: 1,
        name: 'test1',
    },
    {
        id: 4,
        name: '我是插队的那条数据',
    }
    {
        id: 2,
        name: 'test2',
    },
    {
        id: 3,
        name: 'test3',
    },
]

数据变化如下


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


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

最好的办法是使用数组中不会变化的那一项作为key值,对应到项目中,即每条数据都有一个唯一的id,来标识这条数据的唯一性;使用id作为key值,我们再来对比一下向中间插入一条数据,此时会怎么去渲染

虚拟DOM的Diff算法

vue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设:

两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
同一层级的一组节点,他们可以通过唯一的id进行区分。基于以上这两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。

所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

总而言之

key的作用主要是为了高效地更新虚拟DOM。另外vue中在使用相同标签名元素地过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

以上是关于v-for 一定要绑定key值吗?为什么不建议使用index?的主要内容,如果未能解决你的问题,请参考以下文章

Vue中 v-for 绑定key和不绑定key的区别

Vue3 v-for中无key和有key实现的简单解读

v-for一定要与v-bind:key="id"连用

vue.js v-for 一定要与v-bind:key="id" 联用

v-for为什么要加key,能用index作为key么

解决Vue.js中使用v-for提示缺少onbind:key