Vue: v-for的键值key
v-for中的key 我们现在在使用v-for的时候,都必须会加上一个必要的key值,并且很多人会使用index来作为key,其实这样是不太妥当的一种做法。那么v-for中的键值key到底有什么作用呢。 首先看一看vue文档里的说法: emmm,好像还是比较难懂,换种说法 在用v-for更新已渲染的元素列表的时候,会使用就地复用的策略;...
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算法大致相同,其核心是基于两个简单的假设:
- 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
- 同一层级的一组节点,他们可以通过唯一的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。
参考
更多推荐
所有评论(0)