详解如何理解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拖拽并简单保存的实现代码
Nov 28 Javascript
基于AngularJS实现页面滚动到底自动加载数据的功能
Oct 16 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
Jan 15 Javascript
js拖拽功能实现代码解析
Nov 28 Javascript
Angular 4.x 路由快速入门学习
May 03 Javascript
Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
Aug 01 jQuery
JavaScript贪吃蛇小组件实例代码
Aug 20 Javascript
原生javascript实现的全屏滚动功能示例
Sep 19 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
Jan 02 jQuery
基于$.ajax()方法从服务器获取json数据的几种方式总结
Jan 31 Javascript
JavaScript动态加载重复绑定问题
Apr 01 Javascript
vue中多路由表头吸顶实现的几种布局方式
Apr 12 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_diff 的实现)
2008/03/23 PHP
php上传图片到指定位置路径保存到数据库的具体实现
2013/12/30 PHP
非常实用的php弹出错误警告函数扩展性强
2014/01/17 PHP
清华大学出版的事半功倍系列 javascript全部源代码
2007/05/04 Javascript
jquery $.ajax入门应用一
2008/11/19 Javascript
IE8 浏览器Cookie的处理
2009/01/31 Javascript
JavaScript 序列化对象实现代码
2009/12/18 Javascript
优化innerHTML操作(提高代码执行效率)
2011/08/20 Javascript
取得元素的左和上偏移量的方法
2014/09/17 Javascript
javascript日期格式化方法汇总
2015/10/04 Javascript
JavaScript实现简洁的俄罗斯方块完整实例
2016/03/01 Javascript
弹出遮罩层后禁止滚动效果【实现代码】
2016/04/29 Javascript
深入浅析jQuery对象$.html
2016/08/22 Javascript
有关文件上传 非ajax提交 得到后台数据问题
2016/10/12 Javascript
微信小程序之swiper轮播图中的图片自适应高度的方法
2018/04/23 Javascript
js中getter和setter用法实例分析
2018/08/14 Javascript
详解angular2如何手动点击特定元素上的点击事件
2018/10/16 Javascript
mpvue微信小程序多列选择器用法之省份城市选择的实现
2019/03/07 Javascript
解决layer弹出层中表单不起作用的问题
2019/09/09 Javascript
vue-router 控制路由权限的实现
2020/09/24 Javascript
python操作xml文件示例
2014/04/07 Python
Python 正则表达式(转义问题)
2014/12/15 Python
Python json模块使用实例
2015/04/11 Python
python实现电子产品商店
2019/02/26 Python
Python3 批量扫描端口的例子
2019/07/25 Python
python计算n的阶乘的方法代码
2019/10/25 Python
python asyncio 协程库的使用
2021/01/21 Python
Sam’s Club山姆会员商店:沃尔玛旗下高端会员制商店
2017/01/16 全球购物
加拿大最大的箱包及旅游配件零售商:Bentley Leathers
2017/07/19 全球购物
Nike法国官方网站:Nike.com FR
2018/07/22 全球购物
易程科技软件测试笔试
2013/03/24 面试题
工程师自我评价怎么写
2013/09/19 职场文书
有关爱国演讲稿
2014/05/07 职场文书
售后客服个人自我评价
2014/09/14 职场文书
预备党员群众路线思想汇报2014
2014/10/25 职场文书
企业内部管理控制:银行存款控制制度范本
2020/01/10 职场文书