详解如何理解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 相关文章推荐
比较详细的关于javascript 解析json的代码
Dec 16 Javascript
JavaScript 拾漏补遗
Dec 27 Javascript
JavaScript OOP面向对象介绍
Dec 02 Javascript
script标签的 charset 属性使用说明
Dec 04 Javascript
简单实用jquery版三级联动select示例
Jul 04 Javascript
JavaScript中setMonth()方法的使用详解
Jun 11 Javascript
javascript遇到html5的一些表单属性
Jul 05 Javascript
Node.js使用Express创建Web项目详细教程
Mar 31 Javascript
JS中数组与对象的遍历方法实例小结
Aug 14 Javascript
jQuery超简单遮罩层实现方法示例
Sep 06 jQuery
Vue表单控件绑定图文详解
Feb 11 Javascript
vue中通过使用$attrs实现组件之间的数据传递功能
Sep 01 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 array的学习笔记
2012/05/16 PHP
PHP错误机制知识汇总
2016/03/24 PHP
php post换行的方法
2020/02/03 PHP
JS中==与===操作符的比较
2009/03/21 Javascript
关于juqery radio写法的兼容性问题(新老版本jquery)
2010/06/14 Javascript
jQuery循环滚动展示代码 可应用到文字和图片上
2012/05/11 Javascript
基于jQuery的遍历同id元素 并响应事件的代码
2012/06/14 Javascript
JavaScript中的apply和call函数详解
2014/07/20 Javascript
解决jquery实现的radio重新选中的问题
2015/07/03 Javascript
js H5 canvas投篮小游戏
2016/08/18 Javascript
详解nodejs中的process进程
2017/03/19 NodeJs
基于angular实现模拟微信小程序swiper组件
2017/06/11 Javascript
Angular4学习之Angular CLI的安装与使用教程
2018/01/04 Javascript
Vue使用vue-area-linkage实现地址三级联动效果的示例
2018/06/27 Javascript
js与jQuery实现获取table中的数据并拼成json字符串操作示例
2018/07/12 jQuery
js中null与空字符串&quot;&quot;的区别讲解
2019/01/17 Javascript
vue动态注册组件实例代码详解
2019/05/30 Javascript
使用PreloadJS加载图片资源的基础方法详解
2020/02/03 Javascript
[07:01]DOTA2-DPC中国联赛正赛 Aster vs Magma 3月5日 赛后选手采访
2021/03/11 DOTA
为Python的Tornado框架配置使用Jinja2模板引擎的方法
2016/06/30 Python
Java及python正则表达式详解
2017/12/27 Python
python实现类之间的方法互相调用
2018/04/29 Python
TensorFlow实现Logistic回归
2018/09/07 Python
将Python字符串生成PDF的实例代码详解
2019/05/17 Python
python time.sleep()是睡眠线程还是进程
2019/07/09 Python
python+opencv像素的加减和加权操作的实现
2019/07/14 Python
Python csv模块使用方法代码实例
2019/08/29 Python
基于python使用tibco ems代码实例
2019/12/20 Python
css3实现平移效果(transfrom:translate)的示例
2020/11/13 HTML / CSS
购买200个世界上最好的内衣品牌:Bare Necessities
2017/02/11 全球购物
消防器材管理制度
2014/01/28 职场文书
国庆节文艺活动方案
2014/02/03 职场文书
奥巴马连任演讲稿
2014/05/15 职场文书
计划生育标语
2014/06/23 职场文书
反对四风问题自我剖析材料
2014/09/29 职场文书
【海涛教你打DOTA】死灵飞龙第一视角解说
2022/04/01 DOTA