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 相关文章推荐
菜鸟javascript基础资料整理2
Dec 06 Javascript
JS预览图像将本地图片显示到浏览器上
Aug 25 Javascript
js冒泡、捕获事件及阻止冒泡方法详细总结
May 08 Javascript
node.js中的fs.link方法使用说明
Dec 15 Javascript
jQuery中$(function() {});问题详解
Aug 10 Javascript
javascript省市区三级联动下拉框菜单实例演示
Nov 29 Javascript
jQuery Ajax实现跨域请求
Jan 21 Javascript
Vue2.0实现购物车功能
Jun 05 Javascript
Vue2.0子同级组件之间数据交互方法
Feb 28 Javascript
node中间层实现文件上传功能
Jun 11 Javascript
微信小程序 swiper 组件遇到的问题及解决方法
May 26 Javascript
JS实现盒子拖拽效果
Feb 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
一些 PHP 管理系统程序中的后门
2009/08/05 PHP
php将图片保存入mysql数据库失败的解决方法
2014/12/27 PHP
PHP中Notice错误常见解决方法
2017/04/28 PHP
laravel 错误处理,接口错误返回json代码
2019/10/25 PHP
javascript当onmousedown、onmouseup、onclick同时应用于同一个标签节点Element
2010/01/05 Javascript
js换图片效果可进行定时操作
2014/06/09 Javascript
深入浅析NodeJs并发异步的回调处理
2015/12/21 NodeJs
jQuery计算文本框字数及限制文本框字数的方法
2016/03/01 Javascript
JS实现鼠标移上去显示图片或微信二维码
2016/12/14 Javascript
Vue中&quot;This dependency was not found&quot;问题的解决方法
2018/06/19 Javascript
详解vue-cli下ESlint 配置说明
2018/09/03 Javascript
详解使用React制作一个模态框
2019/03/14 Javascript
深入解析vue 源码目录及构建过程分析
2019/04/24 Javascript
解决 viewer.js 动态更新图片导致无法预览的问题
2019/05/14 Javascript
javascript自定义日期比较函数用法示例
2019/07/22 Javascript
layui-table对返回的数据进行转变显示的实例
2019/09/04 Javascript
javascript移动端 电子书 翻页效果实现代码
2019/09/07 Javascript
如何搭建一个完整的Vue3.0+ts的项目步骤
2020/10/18 Javascript
Node.js中的异步生成器与异步迭代详解
2021/01/31 Javascript
浅谈python中copy和deepcopy中的区别
2017/10/23 Python
Python实现自定义顺序、排列写入数据到Excel的方法
2018/04/23 Python
python 地图经纬度转换、纠偏的实例代码
2018/08/06 Python
python实现随机漫步算法
2018/08/27 Python
Python使用itchat 功能分析微信好友性别和位置
2019/08/05 Python
HTML5中的Web Notification桌面右下角通知功能的实现
2018/04/19 HTML / CSS
Ramy Brook官网:美国现代女装品牌
2019/06/18 全球购物
法警的竞聘演讲稿
2014/01/02 职场文书
鲜果饮品店创业计划书
2014/01/21 职场文书
优秀护士获奖感言
2014/02/20 职场文书
2014年感恩母亲演讲稿
2014/05/27 职场文书
咖啡店创业计划书范文
2014/09/15 职场文书
2014年业务员工作总结范文
2014/11/17 职场文书
整改通知书格式
2015/04/22 职场文书
Python类方法总结讲解
2021/07/26 Python
Python中的turtle画箭头,矩形,五角星
2022/03/16 Python
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android