详解如何理解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 相关文章推荐
ASP.NET jQuery 实例18 通过使用jQuery validation插件校验DropDownList
Feb 03 Javascript
js关闭当前页面(窗口)的几种方式总结
Mar 05 Javascript
基于Jquery+Ajax+Json实现分页显示附效果图
Jul 30 Javascript
javascript简单实现类似QQ头像弹出效果的方法
Aug 03 Javascript
全面解析Bootstrap排版使用方法(标题)
Nov 30 Javascript
用JS中split方法实现彩色文字背景效果实例
Aug 24 Javascript
各式各样的导航条效果css3结合jquery代码实现
Sep 17 Javascript
微信小程序如何调用json数据接口并解析
Jun 29 Javascript
Vue的编码技巧与规范使用详解
Aug 28 Javascript
jQuery实现简单QQ聊天框
Aug 27 jQuery
vue+spring boot实现校验码功能
May 27 Vue.js
html5 录制mp3音频支持采样率和比特率设置
Jul 15 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 ci框架中加载css和js文件失败的原因及解决方法
2014/07/29 PHP
跟我学Laravel之安装Laravel
2014/10/15 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
javascript 命名空间以提高代码重用性
2008/11/13 Javascript
JQuery 操作Javascript对象和数组的工具函数小结
2010/01/22 Javascript
jQuery ul标签下拉菜单演示代码
2010/12/11 Javascript
form表单只提交数据而不进行页面跳转的解决方案
2013/09/18 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
express文件上传中间件Multer详解
2016/10/24 Javascript
微信小程序 PHP后端form表单提交实例详解
2017/01/12 Javascript
初探nodeJS
2017/01/24 NodeJs
微信小程序 刷新上拉下拉不会断详细介绍
2017/05/11 Javascript
360提示[高危]使用存在漏洞的JQuery版本的解决方法
2017/10/27 jQuery
编写React组件项目实践分析
2018/03/04 Javascript
vue异步加载高德地图的实现
2018/06/19 Javascript
vue完成项目后,打包成静态文件的方法
2018/09/03 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
公众号SVG动画交互实战代码
2020/05/31 Javascript
在vue中实现嵌套页面(iframe)
2020/07/30 Javascript
小程序实现左滑删除的效果的实例代码
2020/10/19 Javascript
python 中文字符串的处理实现代码
2009/10/25 Python
Python如何import文件夹下的文件(实现方法)
2017/01/24 Python
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
Python利用递归实现文件的复制方法
2018/10/27 Python
Python爬虫requests库多种用法实例
2020/05/28 Python
Python实现EM算法实例代码
2020/10/04 Python
太阳镜仓库,售价20美元或更少:Sunglass Warehouse
2016/09/28 全球购物
英国网上购买门:Direct Doors
2018/06/07 全球购物
行政办公员自我评价分享
2013/12/14 职场文书
2014年党务公开实施方案
2014/02/27 职场文书
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
知识竞赛拉拉队口号
2014/06/16 职场文书
班主任经验交流材料
2014/12/16 职场文书
教师节主持词开场白
2015/05/29 职场文书
2015迎新晚会开场白
2015/05/29 职场文书