深入分析一下 Vue 中不推荐用 index 做 key的原因
时间:2021-12-16 来源:互联网
今天PHP爱好者为您带来在 Vue 中为什么不推荐用 index 做 key?下面本篇文章就来给大家分析一下原因,希望对大家有所帮助,快来收藏吧!
从上面运行结果可以看出来,我们只是添加了一条数据,但是三条数据都需要重新渲染是不是很惊奇,我明明只是插入了一条数据,怎么三条数据都要重新渲染?而我想要的只是新增的那一条数据新渲染出来就行了。
上面我们也讲过 diif 比较方式,下面根据 diff 比较绘制一张图,看看具体是怎么比较的吧
当我们在前面加了一条数据时 index 顺序就会被打断,导致新节点 key 全部都改变了,所以导致我们页面上的数据都被重新渲染了。
下面我们下面生成1000个 DOM 来比较一下采用 index ,和不采用 index 性能比较,为了保证 key 的唯一性我们采用 uuid 作为 key
我们用 index 做为 key 现执行一遍
<template>
<p class="hello">
<ul>
<button @click="addStudent">添加一条数据</button>
<br>
<li v-for="(item,index) in studentList" :key="index">{{item.id}}</li>
</ul>
</p>
</template>
<script>
import uuidv1 from 'uuid/v1'
export default {
name: 'HelloWorld',
data() {
return {
studentList: [{id:uuidv1()}],
};
},
created(){
for (let i = 0; i < 1000; i++) {
this.studentList.push({
id: uuidv1(),
});
}
},
beforeUpdate(){
console.time('for');
},
updated(){
console.timeEnd('for')//for: 75.259033203125 ms
},
methods:{
addStudent(){
const studentObj = { id: uuidv1() };
this.studentList=[studentObj,...this.studentList]
}
}
}
</script>
换成 id 作为 key
<template>
<p class="hello">
<ul>
<button @click="addStudent">添加一条数据</button>
<br>
<li v-for="(item,index) in studentList" :key="item.id">{{item.id}}</li>
</ul>
</p>
</template>
beforeUpdate(){
console.time('for');
},
updated(){
console.timeEnd('for')//for: 42.200927734375 ms
},
从上面比较可以看出,用唯一值作为 key 可以节约开销
数据错位
上述例子可能觉得用 index 做 key 只是影响页面加载的效率,认为少量的数据影响不大,那面下面这种情况,可能用 index 就可能出现一些意想不到的问题了,还是上面的场景,这时我先再每个文本内容后面加一个 input 输入框,并且手动在输入框内填写一些内容,然后通过 button 向前追加一位同学看看
<template>
<p class="hello">
<ul>
<li v-for="(item,index) in studentList" :key="index">{{item.name}}<input /></li>
<br>
<button @click="addStudent">添加一条数据</button>
</ul>
</p>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
studentList: [
{ id: 1, name: '张三', age: 18 },
{ id: 2, name: '李四', age: 19 },
],
};
},
methods:{
addStudent(){
const studentObj = { id: 3, name: '王五', age: 20 };
this.studentList=[studentObj,...this.studentList]
}
}
}
</script>
我们往 input 里面输入一些值,添加一位同学看下效果:
这时候我们就会发现,在添加之前输入的数据错位了。添加之后王五的输入框残留着张三的信息,这很显然不是我们想要的结果。
从上面比对可以看出来这时因为采用 index 作为 key 时,当在比较时,发现虽然文本值变了,但是当继续向下比较时发现DOM 节点还是和原来一摸一样,就复用了,但是没想到 input 输入框残留输入的值,这时候就会出现输入的值出现错位的情况
解决方案
既然知道用 index 在某些情况下带来很不好的影响,那平时我们在开发当中怎么去解决这种情况呢?其实只要保证 key 唯一不变就行,一般在开发中用的比较多就是下面三种情况。
在开发中最好每条数据使用唯一标识固定的数据作为 key,比如后台返回的 ID,手机号,身份证号等唯一值
可以采用 Symbol 作为 key,Symbol 是 ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
let a=Symbol('测试')
let b=Symbol('测试')
console.log(a===b)//false
可以采用 uuid 作为 key ,uuid 是 Universally Unique Identifier 的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符
我们采用上面第一种方案作为 key 在看一下上面情况,如图所示。key 相同的节点都做到了复用。起到了diff 算法的真正作用。
总结
用 index 作为 key 时,在对数据进行,逆序添加,逆序删除等破坏顺序的操作时,会产生没必要的真实 DOM更新,从而导致效率低
用 index 作为 key 时,如果结构中包含输入类的 DOM,会产生错误的 DOM 更新
在开发中最好每条数据使用唯一标识固定的数据作为 key,比如后台返回的 ID,手机号,身份证号等唯一值
如果不存在对数据逆序添加,逆序删除等破坏顺序的操作时,仅用于渲染展示用时,使用 index 作为 key 也是可以的(但是还是不建议使用,养成良好开发习惯)。
原文地址:https://juejin.cn/post/7026119446162997261
作者:政采云前端团队
以上就是深入分析一下 Vue 中不推荐用 index 做 key的原因的详细内容,更多请关注php爱好者其它相关文章!
-
永劫无间多少钱一个红 2024-12-20
-
永劫无间多少钱开一个箱子 2024-12-20
-
阿瑞斯病毒2火铳弹药怎么获得?阿瑞斯病毒2火铳弹药获得方法 2024-12-19
-
阿瑞斯病毒2哈士奇在哪?阿瑞斯病毒2哈士奇获得方法 2024-12-19
-
寻道大千反击流阵容推荐 2024-12-19
-
和平精英性别怎么换?和平精英性别转换方法 2024-12-19