详解如何理解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的图片懒加载js
Jun 30 Javascript
JQUERY简单按钮轮换选中效果实现方法
May 07 Javascript
angular.bind使用心得
Oct 26 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
Jun 06 Javascript
Bootstrap实现提示框和弹出框效果
Jan 11 Javascript
原生Javascript插件开发实践
Jan 18 Javascript
详解vue父子组件间传值(props)
Jun 29 Javascript
tween.js缓动补间动画算法示例
Feb 13 Javascript
浅谈vue项目如何打包扔向服务器
May 08 Javascript
vue项目打包后怎样优雅的解决跨域
May 26 Javascript
微信小程序官方动态自定义底部tabBar的例子
Sep 04 Javascript
JS可断点续传文件上传实现代码解析
Jul 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 file_get_contents抓取Gzip网页乱码的三种解决方法
2013/11/12 PHP
php简单计算页面加载时间的方法
2015/06/19 PHP
使用php实现网站验证码功能【推荐】
2017/02/09 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
php微信开发之音乐回复功能
2018/06/14 PHP
PHP与Perl之间知识点区别整理
2019/03/19 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
2020/02/27 PHP
javascript之大字符串的连接的StringBuffer 类
2007/05/08 Javascript
JS鼠标事件大全 推荐收藏
2011/11/01 Javascript
javascript图片预加载实例分析
2015/07/16 Javascript
js命名空间写法示例
2015/12/18 Javascript
快速掌握Node.js模块封装及使用
2016/03/21 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
jQuery实现的form转json经典示例
2017/10/10 jQuery
element-ui 表格数据时间格式化的方法
2018/08/24 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
2018/09/12 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
Openlayers学习之地图比例尺控件
2020/09/28 Javascript
python读文件逐行处理的示例代码分享
2013/12/27 Python
python处理文本文件并生成指定格式的文件
2014/07/31 Python
python计算文本文件行数的方法
2015/07/06 Python
Python运算符重载详解及实例代码
2017/03/07 Python
matplotlib.pyplot绘图显示控制方法
2019/01/15 Python
Python时间序列缺失值的处理方法(日期缺失填充)
2019/08/11 Python
对Python中 \r, \n, \r\n的彻底理解
2020/03/06 Python
python 多线程共享全局变量的优劣
2020/09/24 Python
PyCharm最新激活码(2020/10/27全网最新)
2020/10/27 Python
Python tkinter之ComboBox(下拉框)的使用简介
2021/02/05 Python
HTML5适合的情人节礼物有纪念日期功能
2021/01/25 HTML / CSS
德国最大的网上足球商店:11teamsports
2019/09/11 全球购物
罗马尼亚在线杂货店:Pilulka.ro
2019/09/28 全球购物
简历中个人自我评价分享
2014/03/15 职场文书
单位租房协议范本
2014/12/03 职场文书
老人院义工活动感想
2015/08/07 职场文书
适合青年人白手起家的创业项目分享
2019/08/16 职场文书