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 相关文章推荐
把textarea中字符串里含有的回车换行替换成&amp;lt;br&amp;gt;的javascript代码
Apr 20 Javascript
JavaScript 仿关机效果的图片层
Dec 26 Javascript
JavaScript参数个数可变的函数举例说明
Oct 10 Javascript
使用微信小程序开发前端【快速入门】
Dec 05 Javascript
ES6(ECMAScript 6)新特性之模板字符串用法分析
Apr 01 Javascript
Vue实现购物车功能
Apr 27 Javascript
详细分析jsonp的原理和实现方式
Nov 20 Javascript
用vue快速开发app的脚手架工具
Jun 11 Javascript
Javascript原生ajax请求代码实例
Feb 20 Javascript
Javascript模拟实现new原理解析
Mar 03 Javascript
JavaScript链式调用原理与实现方法详解
May 16 Javascript
JavaScript如何判断对象有某属性
Jul 03 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
VML绘图板②脚本--VMLgraph.js、XMLtool.js
2006/10/09 PHP
网页游戏开发入门教程二(游戏模式+系统)
2009/11/02 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
2019/10/15 PHP
javaScript 判断字符串是否为数字的简单方法
2009/07/25 Javascript
JS 有名函数表达式全面解析
2010/03/19 Javascript
DOM2非标准但却支持很好的几个属性小结
2012/01/21 Javascript
jQuery中:checked选择器用法实例
2015/01/04 Javascript
基于jQuery实现Ajax验证用户名是否存在实例
2016/03/30 Javascript
什么是JavaScript注入攻击?
2016/09/14 Javascript
从vue源码解析Vue.set()和this.$set()
2018/08/30 Javascript
微信小程序实现基于三元运算验证手机号/姓名功能示例
2019/01/19 Javascript
在layer弹层layer.prompt中,修改placeholder的实现方法
2019/09/27 Javascript
vue-router之解决addRoutes使用遇到的坑
2020/07/19 Javascript
解决vue字符串换行问题(绝对管用)
2020/08/06 Javascript
javascript前端和后台进行数据交互方法示例
2020/08/07 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
2020/10/15 Javascript
用vue设计一个日历表
2020/12/03 Vue.js
vue中父子组件的参数传递和应用示例
2021/01/04 Vue.js
[08:54]《一刀刀一天》之DOTA全时刻18:十九支奔赴西雅图队伍全部出炉
2014/06/04 DOTA
[01:29:31]VP VS VG Supermajor小组赛胜者组第二轮 BO3第一场 6.2
2018/06/03 DOTA
python数字图像处理实现直方图与均衡化
2018/05/04 Python
Python使用pymongo模块操作MongoDB的方法示例
2018/07/20 Python
python实现五子棋小游戏
2020/03/25 Python
Python3实现从排序数组中删除重复项算法分析
2019/04/03 Python
对python中基于tcp协议的通信(数据传输)实例讲解
2019/07/22 Python
解决pytorch-yolov3 train 报错的问题
2020/02/18 Python
python 实现PIL模块在图片画线写字
2020/05/16 Python
解决django 向mysql中写入中文字符出错的问题
2020/05/18 Python
澳大利亚波西米亚风情网上商店:Czarina
2019/03/18 全球购物
好的演讲稿开场白
2013/12/30 职场文书
大学老师推荐信
2014/02/25 职场文书
网站客服岗位职责
2014/04/05 职场文书
产品发布会策划方案
2014/05/12 职场文书
创先争优一句话承诺
2014/05/29 职场文书
三方股东合作协议书
2014/10/28 职场文书
启迪人心的励志语录:脾气永远不要大于本事
2020/01/02 职场文书