<template> <div> <ul> <button @click="addStudent">添加一条数据</button> <br> <li v-for="(item,index) in studentList" :key="item.id">{{item.id}}</li> </ul> </div> </template> beforeUpdate(){ console.time('for'); }, updated(){ console.timeEnd('for')//for: 42.200927734375 ms },
从上面比较可以看出,用唯一值作为 key 可以节约开销
数据错位上述例子可能觉得用 index 做 key 只是影响页面加载的效率,认为少量的数据影响不大,那下面这种情况,用 index 就可能出现一些意想不到的问题了,还是上面的场景,这时我先再每个文本内容后面加一个 input 输入框,并且手动在输入框内填写一些内容,然后通过 button 向前追加一位同学看看
<template> <div> <ul> <li v-for="(item,index) in studentList" :key="index">{{item.name}}<input /></li> <br> <button @click="addStudent">添加一条数据</button> </ul> </div> </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 时,当在比较时,发现虽然文本值变了,但是当继续向下比较时发现 Input 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 也是可以的(但是还是不建议使用,养成良好开发习惯)。
到此这篇关于在 Vue 中为什么不推荐用 index 做 key的文章就介绍到这了,更多相关Vue index 做 key内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章: