详解如何理解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 相关文章推荐
jquery1.4.2 for Visual studio 2010 模板文件
Jul 14 Javascript
jquery ui dialog ie8出现滚动条的解决方法
Dec 06 Javascript
JavaScript实现快速排序(自已编写)
Dec 19 Javascript
jquery多选项卡效果实例代码(附效果图)
Mar 23 Javascript
JS实现鼠标滑过链接改变网页背景颜色的方法
Oct 20 Javascript
ajax图片上传,图片异步上传,更新实例
Dec 30 Javascript
原生js实现放大镜效果
Jan 11 Javascript
帝国cms首页列表页实现点赞功能
Oct 30 Javascript
vue-cli创建的项目,配置多页面的实现方法
Mar 15 Javascript
解决ng-repeat产生的ng-model中取不到值的问题
Oct 02 Javascript
JQuery判断radio单选框是否选中并获取值的方法
Jan 17 jQuery
微信小程序导航栏跟随滑动效果的实现代码
May 14 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里大量数据循环时内存耗尽的方法
2015/10/10 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
Ext对基本类型的扩展 ext,extjs,format
2010/12/25 Javascript
jquery动态添加删除div 具体实现
2013/07/20 Javascript
JS.findElementById()使用介绍
2013/09/21 Javascript
DOM基础教程之使用DOM
2015/01/19 Javascript
js实现根据身份证号自动生成出生日期
2015/12/15 Javascript
浅析jQuery Ajax通用js封装
2016/06/22 Javascript
原生态js,鼠标按下后,经过了那些单元格的简单实例
2016/08/11 Javascript
通过V8源码看一个关于JS数组排序的诡异问题
2017/08/14 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
2018/07/10 Javascript
vue中的ref和$refs的使用
2018/11/22 Javascript
Vue CLI2升级至Vue CLI3的方法步骤
2019/05/20 Javascript
Ant Design Vue 添加区分中英文的长度校验功能
2020/01/21 Javascript
vue 导出文件,携带请求头token操作
2020/09/10 Javascript
Js实现粘贴上传图片的原理及示例
2020/12/09 Javascript
Python ORM框架SQLAlchemy学习笔记之数据查询实例
2014/06/10 Python
详解python3中socket套接字的编码问题解决
2017/07/01 Python
numpy向空的二维数组中添加元素的方法
2018/11/01 Python
python爬虫基础教程:requests库(二)代码实例
2019/04/09 Python
python和JavaScript哪个容易上手
2020/06/23 Python
python opencv角点检测连线功能的实现代码
2020/11/24 Python
selenium3.0+python之环境搭建的方法步骤
2021/02/01 Python
HTML5实现移动端弹幕动画效果
2019/08/01 HTML / CSS
微软台湾官方网站:Microsoft台湾
2018/08/15 全球购物
ToysRus日本官网:玩具反斗城
2018/09/08 全球购物
会计实习生工作总结的自我评价
2013/10/07 职场文书
建筑设计学生的自我评价
2014/01/16 职场文书
国际经济与贸易专业大学生职业规划书
2014/03/01 职场文书
世界读书日的活动方案
2014/08/20 职场文书
校车安全责任书
2014/08/25 职场文书
大学生自荐材料范文
2014/12/30 职场文书
清明节文明祭祀倡议书
2015/04/28 职场文书
MySQL8.0.24版本Release Note的一些改进点
2021/04/22 MySQL
什么是Python装饰器?如何定义和使用?
2022/04/11 Python
MySQL创建管理RANGE分区
2022/04/13 MySQL