详解如何理解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 相关文章推荐
js计算两个时间之间天数差的实例代码
Nov 19 Javascript
jquery跨域请求示例分享(jquery发送ajax请求)
Mar 25 Javascript
javascript获取四位数字或者字母的随机数
Jan 09 Javascript
XML文件转化成NSData对象的方法
Aug 12 Javascript
jquery动画效果学习笔记(8种效果)
Nov 13 Javascript
解决JS无法调用Controller问题的方法
Dec 31 Javascript
微信小程序 教程之WXSS
Oct 18 Javascript
js实现获取鼠标当前的位置
Dec 14 Javascript
JS使用遮罩实现点击某区域以外时弹窗的弹出与关闭功能示例
Jul 31 Javascript
使用JS判断页面是首次被加载还是刷新
May 26 Javascript
利用vue3+ts实现管理后台(增删改查)
Oct 30 Javascript
javascript中导出与导入实现模块化管理教程
Dec 03 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
PHP实现提取一个图像文件并在浏览器上显示的代码
2012/10/06 PHP
PHP 获取远程文件大小的3种解决方法
2013/07/11 PHP
PHP+FFMPEG实现将视频自动转码成H264标准Mp4文件
2014/09/24 PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
2016/03/21 PHP
HTML5附件拖拽上传drop &amp; google.gears实现代码
2011/04/28 Javascript
javaScript复制功能调用实现方案
2012/12/13 Javascript
原生js和jquery中有关透明度设置的相关问题
2014/01/08 Javascript
JavaScript实现获得所有兄弟节点的方法
2015/07/23 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
JavaScript reduce和reduceRight详解
2016/10/24 Javascript
深入解析nodejs HTTP服务
2017/07/25 NodeJs
JS实现的input选择图片本地预览功能示例
2018/08/29 Javascript
vue组件之间数据传递的方法实例分析
2019/02/12 Javascript
深入理解 JS 垃圾回收
2019/06/03 Javascript
优雅的使用javascript递归画一棵结构树示例代码
2019/09/22 Javascript
vue3实现v-model原理详解
2019/10/09 Javascript
vue实现购物车的监听
2020/04/20 Javascript
VueCli4项目配置反向代理proxy的方法步骤
2020/05/17 Javascript
结合axios对项目中的api请求进行封装操作
2020/09/21 Javascript
在Python的Django框架中创建和使用模版
2015/07/15 Python
Python中的异常处理相关语句基础学习笔记
2016/07/11 Python
为什么入门大数据选择Python而不是Java?
2018/03/07 Python
判断python字典中key是否存在的两种方法
2018/08/10 Python
使用Python如何测试InnoDB与MyISAM的读写性能
2018/09/18 Python
python内置函数sorted()用法深入分析
2019/10/08 Python
Python的几种主动结束程序方式
2019/11/22 Python
浅谈Python的方法解析顺序(MRO)
2020/03/05 Python
使用keras根据层名称来初始化网络
2020/05/21 Python
Python多个装饰器的调用顺序实例解析
2020/05/22 Python
Python如何实现Paramiko的二次封装
2021/01/30 Python
英国度假别墅预订:Sykes Cottages
2017/06/12 全球购物
美国最大的存储市场:SpareFoot
2018/07/23 全球购物
营业经理岗位职责
2013/11/10 职场文书
集体婚礼策划方案
2014/02/22 职场文书
房屋分割离婚协议书范本
2014/12/01 职场文书
房地产财务经理岗位职责
2015/04/08 职场文书