vue中使用v-for时为什么不能用index作为key


Posted in Javascript onApril 04, 2020

结论:

  • 更新DOM的时候会出现性能问题
  • 会发生一些状态bug
  • React 中的 key 也是如此
  • 如果已经了解 为什么要用key,可以通过目录直接跳到下一节。

为什么要用key?

Vue 和 React 都实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法。

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

  1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
  2. 同一层级的一组节点,他们可以通过唯一的id进行区分。

基于以上这两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。

用一张图简单说明一下:

vue中使用v-for时为什么不能用index作为key

当页面的数据发生变化时,Diff算法只会比较同一层级的节点:

如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点。

如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。

举个栗子:

vue中使用v-for时为什么不能用index作为key

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

vue中使用v-for时为什么不能用index作为key

即把C更新成F,D更新成C,E更新成D,最后再插入E,这样效率不高,且性能不够好。

但是,如果使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

vue中使用v-for时为什么不能用index作为key

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

这里,也建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单。

为什么不能用index作为key?

举个栗子:

<template>
  <div v-for="(item, index) in list" :key="index" >{{item.name}}</div>
</template>
const list = [
  {
    id: 1,
    name: "Person1"
  },
  {
    id: 2,
    name: "Person2"
  },
  {
    id: 3,
    name: "Person3"
  },
  {
    id:4,
    name:"Person4"
  }
];

此时,删除 “Person4” 是正常的,但是如果我删除 “Person2” 就会出现问题。

删除前

key id index name
0 1 0 Person1
1 2 1 Person2
2 3 2 Person3
3 4 3 Person4

删除后

key id index name
0 1 0 Person1
1 3 1 Person3
2 4 2 Person4

这个时候,除了 Person1 之外,剩下的 Person3、Person4,因为被发现与相应 key 的绑定关系有变化,所以被重新渲染,这会影响性能。
如果此时 list 的 item 是 select 的选项,其中 Person3 是选中的,这个时候 Person2 被删除了,用 index 作为 key 就会变成是 Person4 选中的了,这就产生了bug。

如果使用唯一id作为key,删除 Person2 后,剩下的元素因为与 key 的关系没有发生变化,都不会被重新渲染,从而达到提升性能的目的。此时,list 的 item 作为 select 的选项,也不会出现上面所描述的bug。

到此这篇关于vue中使用v-for时为什么不能用index作为key的文章就介绍到这了,更多相关vue v-for不能用index作为key内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Using the TextRange Object
Oct 14 Javascript
Ajax,UTF-8还是GB2312 eval 还是execScript
Nov 13 Javascript
理解Javascript_13_执行模型详解
Oct 20 Javascript
IE下JS读取xml文件示例代码
Aug 05 Javascript
js检查是否关闭浏览器的方法
Aug 02 Javascript
关于vue中watch检测到不到对象属性的变化的解决方法
Feb 08 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
Aug 31 Javascript
ztree加载完成后显示勾选节点的实现代码
Oct 22 Javascript
Vue路由守卫之路由独享守卫
Sep 25 Javascript
JavaScript 装逼指南(js另类写法)
May 10 Javascript
Angular利用HTTP POST下载流文件的步骤记录
Jul 26 Javascript
vue实现列表拖拽排序的功能
Nov 02 Javascript
详解为什么Vue中不要用index作为key(diff算法)
Apr 04 #Javascript
原理深度解析Vue的响应式更新比React快
Apr 04 #Javascript
Vue的data、computed、watch源码浅谈
Apr 04 #Javascript
VUE table表格动态添加一列数据,新增的这些数据不可以编辑(v-model绑定的数据不能实时更新)
Apr 03 #Javascript
mpvue实现微信小程序快递单号查询代码
Apr 03 #Javascript
mpvue网易云短信接口实现小程序短信登录的示例代码
Apr 03 #Javascript
javascript用defineProperty实现简单的双向绑定方法
Apr 03 #Javascript
You might like
提升PHP速度全攻略
2006/10/09 PHP
phpExcel中文帮助手册之常用功能指南
2014/08/18 PHP
详解WordPress中提醒安装插件以及隐藏插件的功能实现
2015/12/25 PHP
Zend Framework处理Json数据方法详解
2016/12/09 PHP
TP5框架实现自定义分页样式的方法示例
2020/04/05 PHP
javascript 关于# 和 void的区别分析
2009/10/26 Javascript
JS定时器实例
2013/04/17 Javascript
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
vue-router2.0 组件之间传参及获取动态参数的方法
2017/11/10 Javascript
js实现简单选项卡功能
2020/03/23 Javascript
Vue中保存数据到磁盘文件的方法
2018/09/06 Javascript
JS匿名函数内部this指向问题详析
2019/05/10 Javascript
node删除、复制文件或文件夹示例代码
2019/08/13 Javascript
vue.js 解决v-model让select默认选中不生效的问题
2020/07/28 Javascript
Vue常用API、高级API的相关总结
2021/02/02 Vue.js
Vue实现todo应用的示例
2021/02/20 Vue.js
压缩包密码破解示例分享(类似典破解)
2014/01/17 Python
Python实现递归遍历文件夹并删除文件
2016/04/18 Python
分析python动态规划的递归、非递归实现
2018/03/04 Python
使用pandas的DataFrame的plot方法绘制图像的实例
2018/05/24 Python
详解Python匿名函数(lambda函数)
2019/04/19 Python
python发送多人邮件没有展示收件人问题的解决方法
2019/06/21 Python
Pandas之MultiIndex对象的示例详解
2019/06/25 Python
Django框架获取form表单数据方式总结
2020/04/22 Python
django 外键创建注意事项说明
2020/05/20 Python
python 实时调取摄像头的示例代码
2020/11/25 Python
HTML5 Canvas入门学习教程
2016/03/17 HTML / CSS
日本土著品牌,综合型购物网站:Cecile
2016/08/23 全球购物
全球领先的中国制造商品在线批发平台:DHgate
2020/01/28 全球购物
.NET程序员的几道面试题
2012/06/01 面试题
环保建议书
2014/03/12 职场文书
难忘的一天教学反思
2014/04/30 职场文书
教师节感恩老师演讲稿
2014/08/28 职场文书
2014年学习部工作总结
2014/11/12 职场文书
生死抉择观后感
2015/06/09 职场文书
《落花生》教学反思
2016/02/16 职场文书