摘要

本文结合源码说明了key的作用,给出了一个不写key的反例,并分析了原因。

内容

  • key的作用

  • 不写key会出的bug及原因分析

  • key的实践方案

key的作用

在数据变化前后,vue会得到两个虚拟dom树,并依次比较两个虚拟dom树中哪些结点有变动,从而决定去做具体的更新。这里有一个操作要做:比较两个结点是不是同一结点,这个操作在源码是通过sameVnode来完成的。见如下代码。

 // https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.jsfunction sameVnode (a, b) {  return (    a.key === b.key && (      (        a.tag === b.tag &&        a.isComment === b.isComment &&        isDef(a.data) === isDef(b.data) &&        sameInputType(a, b)      ) || (        isTrue(a.isAsyncPlaceholder) &&        a.asyncFactory === b.asyncFactory &&        isUndef(b.asyncFactory.error)      )    )  )}

假设我们给一组元素中的每一项都设置了一个唯一的标识,则a.key===b.key就可以更快地返回结果,这就是提升性能的关键点。

在实践中,渲染一组列表时,key往往是唯一标识(可能其它的条件是相同的),所以,如果不定义key,vue只能认为比较的两个节点是同一个 (undefined===undefined),哪怕它们实际上不是,这导致了频繁更新元素,使得整个patch过程比较低效,影响性能。有些特殊的时候甚至会有一些bug。

bug来了

下面这一段代码是硬编出来的,用它来说明如果在v-for循环中不写key,或者key没有正确使用会带来的后果。

 <div id="app" style="padding:20px">  <coma v-for="(it,idx) in list" :i="idx" @click="d">{{it}}coma>div><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js">script><script>  Vue.component('coma',{    data() {      return {        v: Math.random()      }    },    template: `
-{{v}} 点我删除  

`,    props: ['i'] })  new Vue({    el: "#app",    data: {      list: [1, 2,3,4,5]   },    methods: {      d(idx) {        this.list.splice(idx, 1)     }   } })script>

bug描述:当在某一项上点击删除时,它会删除最后一项,而不是删除当前项(请把注意力放在最后一项)。

原因分析

vue是通过虚拟dom来表示描述真实dom的,在去更新视图之前,要对前后两个虚拟dom树进行分析,以得出它们的区别。如果不设置key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。看官网 https://cn.vuejs.org/v2/api/#key

分析一下上面bug, 以在第2项上点击为例。

期待的情况,在点击前的数据:

 1,2,3

在点击之后的数据

 1,3 // 第二项被删除了。

但是由于没有设置key,此间产生的变化是:

  1. 把原来的第2项中的2改成3

  2. 把第3项删除掉。

所以会导致序号异常,且最后一项被删除了。

还有一个bug可以看这里https://codesandbox.io/s/vue-v-for-key-50x89。类似的情况还会发生在使用了v-transition时。

推荐设置key

可以通过如下的改进来避免上面的坑:

  1. 给列表中的数据项添加唯一的id

 data: {   list: [{id:1,value:1},{id:2,value:3},{id:3,value:3}]},
  1. 修改视图

 {{it.value}}

这样,在删除第二项时,vue会做出正确的判断:删除第二个组件。

小结

  • key的作用主要是为了更高效的对比虚拟dom中的某个节点是不是相同节点,是用来提高diff算法的性能表现。更具体一点,vue在patch过程(执行diff的算法,可翻译为打补丁算法)中判断两个节点是否是相同节点,key值相同是一个必要条件。

  • key会提升效率。某些特殊情况下,不写key会出错。

  • 在使用v-for循环时,尽量避免直接使用数组的下标为key,因为它们在做删除操作时可能会导致渲染异常。

  • 最好是将key设成数据项中的主键:可以把一项与另一项区别开的值。

版权信息:凡人进阶。转载请标明出处。如果对您有帮助,您可以:

  • 转发他人。

  • 小额打赏。

  • 关注本号。

vue 相同的id不合并_vue中key的作用相关推荐

  1. 26.Vue列表渲染中key的作用与原理(内含虚拟DOM的对比算法详解)

    目录 1.暴露问题,使用index作为key 2.使用唯一标识p.id作为key 3.不写key的配置 4.key的工作原理及虚拟DOM的对比算法 5.总结 25.Vue列表渲染_爱米酱的博客-CSD ...

  2. 【Vue】中Key的作用

    Vue中key的作用 虚拟DOM 虚拟DOM 本质上是一个js对象 ,通过对象来表示真实的DOM结构. key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据 新数据 生成 新的虚拟DO ...

  3. 【Day08】请简述虚拟 DOM 中 Key 的作用和好处

    请简述虚拟 DOM 中 Key 的作用和好处 官网地址:https://cn.vuejs.org/v2/api/#key key 的作用 key 的特殊 attribute 主要用在 Vue 的虚拟 ...

  4. vue列表渲染中key的作用_vue中:key的作用

    因为不理解 :key(v-bind:key),网上查了一些的资料,这篇写得非常不错,很简洁清楚. 其实不只是vue,react中在执行列表渲染时也会要求给每个组件添加上key这个属性. 要解释key的 ...

  5. vue 怎么全局到入常量_Vue 中如何定义全局的变量和常量(转)

    17.6k 次阅读  ·  读完需要 10 分钟 7 Vue 中如何定义全局的变量和常量 我想要定义一个变量, 在项目的任何地方都可以访问到, 不需要每一次使用的时候, 都引入. 尝试1: 创建 gl ...

  6. vue列表渲染中key的作用_列表渲染和Vue的v-for指令

    Web渲染是Web开发中最常用的实战之一.动态列表渲染通常用于简洁友好的格式向用户渲染一系列相似的分组信息.在我们使用的每个Web应用程序中,都可以看到很多内容列表被用于Web应用程序当中. 在这篇文 ...

  7. vue中key的作用及案例

    1.key的作用 假设现在有一个需求,在页面循环data中的数组. <div id="app"><ul><li v-for="(item, ...

  8. <router-view :key=“key“/>中key的作用

    router-view 中key作用, 你可以 router-view 当做是一个容器,它渲染的组件是你使用 vue-router 指定的. 这里router-view 有一个key的属性,这个key ...

  9. java中key的作用_key word ‘final’ 在java 中作用

    随着硬件的发展,一般的芯片不会用于裸跑,像android things 这样的系统会越来越多,在嵌入式中c++/java的应用将会越来越多.而且我感觉嵌入式工程师掌握android app的基本开发是 ...

最新文章

  1. 360°透视:云原生架构及设计原则
  2. Java 连接数据库(SQL Server)ODBC配置详情
  3. 浏览器阻挡cookies_解决WordPress登录提示”Cookies被阻止或者您的浏览器不支持”...
  4. XP系统和Sever2003系统现实定时开关机
  5. telnet不能用,提示:-bash: telnet: command not found
  6. Linux文件和目录的属性及权限
  7. 蓝桥杯 ALGO-117 算法训练 友好数
  8. HDU2203 亲和串【字符串】
  9. php post重复提交session,PHP加Session防止表单重复提交的解决方法
  10. 详解C/C++预处理器
  11. PDF转图片文字丢失问题解决
  12. c语言编程界面优化输出图形,C语言编程实例—输出指定图形
  13. Nike Zoom LeBron 15 Performance Review
  14. 京瓷打印机m5521cdn_京瓷ECOSYS M5521cdn驱动
  15. 第三十三章 SQL函数 COT
  16. 工业智能网关BL110应用之四十三:网口采集欧姆龙PLC的配置
  17. Codeforces 686D. Kay and Snowflake
  18. 弹窗拦截小帮手------火绒
  19. 国内java报表软件简单对比
  20. 弱口令漏洞与验证码绕过——渗透day04

热门文章

  1. 聊聊 Kafka: Kafka 的基础架构
  2. 某程序员吐槽自己之前的外包同事能力不行,经常给同事挖坑,却面过了头条!只因为会刷题!头条招人这么不靠谱?...
  3. 遇到网络问题你是怎么解决的?安琪拉有二招
  4. 阿里老员工吐槽:新员工水平差!不服管理!还不加班!我要汇报经理让对方无法转正!...
  5. 基于深度学习的可疑活动视频分析
  6. 关于中台的思考与尝试
  7. pyspider积累
  8. 知乎好物推荐设计与实现
  9. 排序算法---选择排序(java版)
  10. 手机端登陆github产生ssl handshake aborted error如何解决?