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 相关文章推荐
Visual Studio中的jQuery智能提示设置方法
Mar 27 Javascript
javascript 基础篇4 window对象,DOM
Mar 14 Javascript
jquery js 重置表单 reset()具体实现代码
Aug 05 Javascript
JavaScript实现跨浏览器的添加及删除事件绑定函数实例
Aug 04 Javascript
JavaScript function函数种类详解
Feb 22 Javascript
jQuery增加与删除table列的方法
Mar 01 Javascript
jQuery选择器总结之常用元素查找方法
Aug 04 Javascript
详解Angularjs 如何自定义Img的ng-load 事件
Feb 15 Javascript
深入理解Commonjs规范及Node模块实现
May 17 Javascript
浅谈node中的exports与module.exports的关系
Aug 01 Javascript
学习React中ref的两个demo示例
Aug 14 Javascript
Vue使用自定义指令实现拖拽行为实例分析
Jun 06 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
ThinkPHP水印功能实现修复PNG透明水印并增加JPEG图片质量可调整
2014/11/05 PHP
php+mysql数据库查询实例
2015/01/21 PHP
PHP调用.NET的WebService 简单实例
2015/03/27 PHP
详解WordPress中创建和添加过滤器的相关PHP函数
2015/12/29 PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
2016/12/15 PHP
php生成二维码不保存服务器还有下载功能的实现代码
2018/08/09 PHP
php fread函数使用方法总结
2019/05/28 PHP
Javascript学习笔记8 用JSON做原型
2010/01/11 Javascript
ExtJS 学习专题(一) 如何应用ExtJS(附实例)
2010/03/11 Javascript
ModelDialog JavaScript模态对话框类代码
2011/04/17 Javascript
jQuery获取样式中的背景颜色属性值/颜色值
2012/12/17 Javascript
Json和Jsonp理论实例代码详解
2013/11/15 Javascript
JavaScript分页功能的实现方法
2015/04/25 Javascript
BootStrap中的表单大全
2016/09/07 Javascript
vue router路由嵌套不显示问题的解决方法
2017/06/17 Javascript
Node.js 使用jade模板引擎的示例
2018/05/11 Javascript
js最实用string(字符串)类型的使用及截取与拼接详解
2019/04/26 Javascript
React 全自动数据表格组件——BodeGrid的实现思路
2019/06/12 Javascript
layui 实现表格某一列显示图标
2019/09/19 Javascript
Vue简单实现原理详解
2020/05/07 Javascript
[01:10:16]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第一局
2016/02/27 DOTA
用Python编写简单的定时器的方法
2015/05/02 Python
深入理解NumPy简明教程---数组1
2016/12/17 Python
老生常谈Python基础之字符编码
2017/06/14 Python
Python实现读取邮箱中的邮件功能示例【含文本及附件】
2017/08/05 Python
Python实现KNN邻近算法
2021/01/28 Python
分享vim python缩进等一些配置
2018/07/02 Python
python 遍历目录(包括子目录)下所有文件的实例
2018/07/11 Python
Pycharm中配置远程Docker运行环境的教程图解
2020/06/11 Python
澳大利亚旅游网站:Lastminute
2017/08/07 全球购物
白俄罗斯女装和针织品网上商店:Presli.by
2019/10/13 全球购物
初中生期末考试的自我评价
2013/12/17 职场文书
公民代理授权委托书
2014/09/24 职场文书
故宫导游词
2015/01/31 职场文书
免职通知
2015/04/23 职场文书
导游词之无锡古运河
2019/11/14 职场文书