Vue: v-for的键值key

v-for中的key

       我们现在在使用v-for的时候,都必须会加上一个必要的key值,并且很多人会使用index来作为key,其实这样是不太妥当的一种做法。那么v-for中的键值key到底有什么作用呢。

       首先看一看vue文档里的说法:

      emmm,好像还是比较难懂,换种说法
      在用v-for更新已渲染的元素列表的时候,会使用就地复用的策略;这就是说列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改了就重新渲染,不然就复用之前的元素。

      总结一下,就是通过key值来提升渲染的效率。

      举个?
      

const list = [
    {
        id:1,
        name:'test'
    },
    {
        id:2,
        name:'test2',
    },
    {
        id:3,
        name:'test3'
    },
]
<div v-for="(item,index) in list :key="index">{{item.name}}</div>

这个场景在我们开发的时候经常会碰到,因为不加key,vue现在会直接报错,所以我使用index作为key;
下面再举两个例子来看数据更新后的情况。

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

const list = [
    {
        id: 1,
        name: 'test1',
    },
    {
        id: 2,
        name: 'test2',
    },
    {
        id: 3,
        name: 'test3',
    },
    {
        id: 4,
        name: '我是在最后添加的一条数据',
    },
]

此时前三条数据直接复用之前的,新渲染最后一条数据,此时用index作为key,没有任何问题;

2.在中间插入一条数据

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

此时更新渲染数据,通过index定义的key去进行前后数据的对比,发现

之前的数据                         之后的数据

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值发生了变化;
这时候就可以体现出了一个效率问题,只插入了一条数据,却要重新渲染三条数据;

所以我们需要可以想办法让数组中不会变化的数据的key值也不变,所以不能通过index来设置key值,应该设置一个唯一的id来标识数据的唯一性;我们修改之后再来对比一下渲染的效率:

之前的数据                         之后的数据

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

 对比可以发现,只有一条数据发生了变化,因为其他数据的id都没变,所以key值也没变,所以只需要渲染这一条新的数据即可
所以一般推荐使用id作为key值来配合v-for使用

下面大致从虚拟DOM的Diff算法实现的角度去解释一下:

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

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

引用React’s diff algorithm中的例子:

 当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。
比如一下这个情况:

我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:

 

即把C更新成F,D更新成C,E更新成D,最后再插入E,很没有效率

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

所以用一句话来概括,key的作用主要是为了高效的更新虚拟DOM。

参考

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值