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 相关文章推荐
利用Ext Js生成动态树实例代码
Sep 08 Javascript
了解jQuery技巧来提高你的代码
Jan 08 Javascript
用js实现的模拟jquery的animate自定义动画(2.5K)
Jul 20 Javascript
eval的两组性能测试数据
Aug 17 Javascript
jQuery中复合属性选择器用法实例
Dec 31 Javascript
JS实现点击按钮控制Div变宽、增高及调整背景色的方法
Aug 05 Javascript
js图片翻书效果代码分享
Aug 20 Javascript
基于JavaScript实现动态添加删除表格的行
Feb 01 Javascript
jQuery插件 Jqplot图表实例
Jun 18 Javascript
使用plupload自定义参数实现多文件上传
Jul 19 Javascript
AngularJS 模块详解及简单实例
Jul 28 Javascript
各种选择框jQuery的选中方法(实例讲解)
Jun 27 jQuery
详解为什么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写杨辉三角实例代码
2011/07/17 PHP
PHP操作文件类的函数代码(文件和文件夹创建,复制,移动和删除)
2011/11/10 PHP
php中如何防止表单的重复提交
2013/08/02 PHP
php数组操作之键名比较与差集、交集赋值的方法
2014/11/10 PHP
Thinkphp关闭缓存的方法
2015/06/26 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
2015/12/22 PHP
PHP如何将XML转成数组
2016/04/04 PHP
Yii2使用dropdownlist实现地区三级联动功能的方法
2016/07/18 PHP
30个最佳jQuery Lightbox效果插件分享
2011/04/11 Javascript
js Html结构转字符串形式显示代码
2011/11/15 Javascript
js获得地址栏?问号后参数的方法
2013/08/08 Javascript
JSON传递bool类型数据的处理方式介绍
2013/09/18 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
jquery移除、绑定、触发元素事件使用示例详解
2014/04/10 Javascript
js怎么覆盖原有方法实现重写
2014/09/04 Javascript
JS中的form.submit()不能提交表单的错误原因
2014/10/08 Javascript
js改变Iframe中Src的方法
2015/05/05 Javascript
深入浅析JavaScript面向对象和原型函数
2016/02/06 Javascript
深入理解Javascript中的自执行匿名函数
2016/06/03 Javascript
BootStrap table使用方法分析
2016/11/08 Javascript
jQuery实现QQ空间汉字转拼音功能示例
2017/07/10 jQuery
集成vue到jquery/bootstrap项目的方法
2018/02/10 jQuery
如何换个角度使用VUE过滤器详解
2019/09/11 Javascript
使用70行Python代码实现一个递归下降解析器的教程
2015/04/17 Python
Python PyQt5 Pycharm 环境搭建及配置详解(图文教程)
2019/07/16 Python
python @classmethod 的使用场合详解
2019/08/23 Python
Python实现串口通信(pyserial)过程解析
2019/09/25 Python
CSS3对背景图片的裁剪及尺寸和位置的设定方法
2016/03/07 HTML / CSS
AT&T Wireless:手机、无限数据计划和配件
2018/06/03 全球购物
Black Halo官方网站:购买连衣裙、礼服和连体裤
2018/06/13 全球购物
如何进行Linux分区优化
2016/09/13 面试题
小学音乐教学反思
2014/02/05 职场文书
模具设计与制造专业求职信
2014/07/19 职场文书
运动会演讲稿200字
2014/08/25 职场文书
公司禁烟通知
2015/04/23 职场文书
Python数据可视化之用Matplotlib绘制常用图形
2021/06/03 Python