详解如何理解vue的key属性


Posted in Javascript onApril 14, 2019

如果没有这个属性的时候vue应用 in-place patch(就地复用)策略。列表里的顺序发生改变的时候比如shuffle(列表打乱)的时候,vue为了提升性能,不会移动dom元素,只是更新相应元素的内容节点。

就地复用的弊端

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

如上引用自官网,这个模式就是上面的“就地复用”策略。那么是不是依赖子组件状态的列表渲染采用上面的模式就出问题了呢。如下测试代码:

<ul>
  <li v-for="item in items">
   <p>{{ item.title }}</p>
   <p>{{ item.des }}</p>
   <tweet-component></tweet-component>
  </li>
  </ul>
 <script>
  Vue.component("tweet-component", {
  template: `
   <div class="tweet">
   <div class="box">
    {{xixi}}
   </div>
   </div>
  `,
  data() {
   return {
   xixi: Math.random()
   };
  }
  });
  new Vue({
  el: "#app",
  data: {
   items: [
   { title: "nihao1", des: "xiexie1" },
   { title: "nihao2", des: "xiexie2" },
   { title: "nihao3", des: "xiexie3" }
   ]
  },
  methods: {
   shuffle() {
    // lodash的shuffle方法
   this.items = _.shuffle(this.items);
   }
  }
  });
 </script>

操作如下:

详解如何理解vue的key属性 

问题出现了:发生变化时,子组件 没有更新

ps: 测试临时 DOM 状态 (例如:表单输入值)可以参考这个链接 List Rendering and Vue's v-for Directive

key的作用

这个时候引入 key 就可以解决这个问题。 key 的作用是给予一个节点唯一的身份识别,有相同父元素的子元素必须有独特的 key 。这样它可以前后对比,算出哪些节点是要重复使用或者调整顺序。比如原先的 key 的顺序是 i1,i2,i3 ,之后变成了 i2,i1,i3 这个时候只要i3保持不变,把i2 insertBefore 到i1节点前就行了(以上是举例,vue具体怎么操作的需要去研究源码)。如果是利用数组的 index 来作为 key 则两次对比没有区别,就会出现上面动图里出现的子组件没有更新的情况。

可以通过查看下面两个动图查看dom节点的变化。第一个gif是没有使用 key ,第二个是使用了 key 。可以看到我点了按钮后,第一个只是更新 <p> 标签的内容节点。第二个是移动了某一项的 <li> 标签。

详解如何理解vue的key属性详解如何理解vue的key属性

ps: 另外可以通过chrome的dom断点功能查看子元素的插入删除。

DOM 更改断点

key的其他用途

key不是只能用在v-for上还可以用在其他元素上。如下代码

<div v-if="toggle">Hello</div>
<div v-else>Goodbye</div>

切换toggle时,它也是切换div。如果你想用上enter/leave animations时,即节点插入和删除的时候的动画时就要打破这个复用,如下:

<transition>
 <div v-if="toggle" key="1">Hello</div>
 <div v-else key="2">Goodbye</div>
</transition>

总结

如果你的列表不发生变化,或者你只是往列表最后一项添加元素则看似不必要增加 key 字段。但是你的项目中有很多列表的时候,你有的需要加 key ,有的不需要加。还不如所有的都加上呢避免别人理解困难(^._.^)ノ。

参考链接

https://vuejs.org/v2/guide/list.html#key

vuejs.org/v2/api/#key

https://forum.vuejs.org/t/simple-clarification-of-when-using-key-with-v-for-is-appropriate-and-why/28966/5

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery 注意事项 与原因分析
Apr 24 Javascript
jquery 新手学习常见问题解决方法
Apr 18 Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
Jan 25 Javascript
谈谈关于JavaScript 中的 MVC 模式
Apr 11 Javascript
javascript实现状态栏文字首尾相接循环滚动的方法
Jul 22 Javascript
理解jquery事件冒泡
Jan 03 Javascript
基于BootStrap Metronic开发框架经验小结【六】对话框及提示框的处理和优化
May 12 Javascript
可输入文字查找ajax下拉框控件 ComBox的实现方法
Oct 25 Javascript
详解webpack的配置文件entry与output
Aug 21 Javascript
vue 动态改变静态图片以及请求网络图片的实现方法
Feb 07 Javascript
vue3.0 CLI - 2.5 - 了解组件的三维
Sep 14 Javascript
element-ui中Table表格省市区合并单元格的方法实现
Aug 07 Javascript
axios+Vue实现上传文件显示进度功能
Apr 14 #Javascript
Vue 使用formData方式向后台发送数据的实现
Apr 14 #Javascript
说说如何使用Vuex进行状态管理(小结)
Apr 14 #Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
Apr 14 #Javascript
浅谈Vue页面级缓存解决方案feb-alive(上)
Apr 14 #Javascript
vue 实现小程序或商品秒杀倒计时
Apr 14 #Javascript
js中async函数结合promise的小案例浅析
Apr 14 #Javascript
You might like
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
php自定文件保存session的方法
2014/12/10 PHP
php通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
php实现Session存储到Redis
2015/11/11 PHP
2款PHP无限级分类实例代码
2015/11/11 PHP
php获取字符串前几位的实例(substr返回字符串的子串用法)
2017/03/08 PHP
PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解
2019/06/14 PHP
javascript开发技术大全-第3章 js数据类型
2011/07/03 Javascript
VBS通过WMI监视注册表变动的代码
2011/10/27 Javascript
js字符串转成JSON
2013/11/07 Javascript
自己编写的支持Ajax验证的JS表单验证插件
2015/05/15 Javascript
原生js实现图片层叠轮播切换效果
2016/02/02 Javascript
jQuery获取cookie值及删除cookie用法实例
2016/04/15 Javascript
js实现上传文件添加和删除文件选择框
2016/10/24 Javascript
jQuery实现的页面弹幕效果【测试可用】
2018/08/17 jQuery
如何在微信小程序中实现Mixins方案
2019/06/20 Javascript
Vue.js获取手机系统型号、版本、浏览器类型的示例代码
2020/05/10 Javascript
[04:42]2015国际邀请赛CDEC战队晋级之路
2015/08/13 DOTA
[01:00:17]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第二场 1月25日
2021/03/11 DOTA
python解析json实例方法
2013/11/19 Python
Python实现的简单发送邮件脚本分享
2014/11/07 Python
在Linux命令行终端中使用python的简单方法(推荐)
2017/01/23 Python
Pycharm学习教程(7)虚拟机VM的配置教程
2017/05/04 Python
Python实现简单生成验证码功能【基于random模块】
2018/02/10 Python
python GUI库图形界面开发之PyQt5中QMainWindow, QWidget以及QDialog的区别和选择
2020/02/26 Python
sklearn和keras的数据切分与交叉验证的实例详解
2020/06/19 Python
C#面试问题
2016/07/29 面试题
全运会口号
2014/06/20 职场文书
乡镇领导班子四风对照检查材料
2014/09/27 职场文书
2014年检察院个人工作总结
2014/12/09 职场文书
五四青年节活动总结
2015/02/10 职场文书
鲁冰花观后感
2015/06/10 职场文书
女方家长婚礼答谢词
2015/09/29 职场文书
导游词之徐州-云龙山
2019/09/29 职场文书
python flask框架快速入门
2021/05/14 Python
详解非极大值抑制算法之Python实现
2021/06/28 Python