详解如何理解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 Excel操作知识点
Apr 24 Javascript
JQuery 构建客户/服务分离的链接模型中Table分页代码效率初探
Jan 22 Javascript
jQuery中:only-child选择器用法实例
Jan 03 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
Jan 08 Javascript
关于vue.js弹窗组件的知识点总结
Sep 11 Javascript
vue使用watch 观察路由变化,重新获取内容
Mar 08 Javascript
Bootstrap学习笔记 轮播(Carousel)插件
Mar 21 Javascript
实例解析ES6 Proxy使用场景介绍
Jan 08 Javascript
JS实现匀速与减速缓慢运动的动画效果封装示例
Aug 27 Javascript
JS实现方形抽奖效果
Aug 27 Javascript
Vue瀑布流插件的使用示例
Sep 19 Javascript
three.js实现炫酷的全景3D重力感应
Dec 30 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 中英文语言转换类
2011/09/07 PHP
PHP去除字符串最后一个字符的三种方法实例
2017/03/01 PHP
PHP语言对接抖音快手小红书视频/图片去水印API接口源码
2020/08/11 PHP
JQuery中解决重复动画的方法
2016/10/17 Javascript
基于slideout.js实现移动端侧边栏滑动特效
2016/11/28 Javascript
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
js Element Traversal规范中的元素遍历方法
2018/04/19 Javascript
一步快速解决微信小程序中textarea层级太高遮挡其他组件
2019/03/04 Javascript
Vue插槽原理与用法详解
2019/03/05 Javascript
vue通过video.js解决m3u8视频播放格式的方法
2019/07/30 Javascript
JS中的算法与数据结构之队列(Queue)实例详解
2019/08/20 Javascript
微信小程序实现左侧滑栏过程解析
2019/08/26 Javascript
vue实现移动端省市区选择
2019/09/27 Javascript
Vue.extend 编程式插入组件的实现
2019/11/18 Javascript
JavaScript中this的学习笔记及用法整理
2020/02/17 Javascript
解决Nuxt使用axios跨域问题
2020/07/06 Javascript
解决Vue-cli无法编译es6的问题
2020/10/30 Javascript
详解vite+ts快速搭建vue3项目以及介绍相关特性
2021/02/25 Vue.js
[43:33]EG vs Spirit Supermajor 败者组 BO3 第一场 6.4
2018/06/05 DOTA
python的正则表达式re模块的常用方法
2013/03/09 Python
Python实现全局变量的两个解决方法
2014/07/03 Python
用Python实现读写锁的示例代码
2018/11/05 Python
Python设计模式之解释器模式原理与用法实例分析
2019/01/10 Python
Python短信轰炸的代码
2020/03/25 Python
纯CSS3大转盘抽奖示例代码(响应式、可配置)
2017/01/13 HTML / CSS
教你使用Canvas处理图片的方法
2017/11/28 HTML / CSS
三星印度官网:Samsung印度
2019/08/03 全球购物
介绍一下javax.servlet.Servlet接口及其主要方法
2015/11/30 面试题
历史专业学生的自我评价
2014/02/28 职场文书
医院信息公开实施方案
2014/05/09 职场文书
教师正风肃纪剖析材料
2014/10/20 职场文书
教师见习总结范文
2015/06/23 职场文书
学校远程教育工作总结
2015/08/11 职场文书
小学一年级班主任工作经验交流材料
2015/11/02 职场文书
JavaScript中的宏任务和微任务详情
2021/11/27 Javascript
Selenium浏览器自动化如何上传文件
2022/04/06 Python