详解如何理解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中暂停功能的实现代码
Mar 04 Javascript
JS中confirm,alert,prompt函数使用区别分析
Apr 01 Javascript
为你的网站增加亮点的9款jQuery插件推荐
May 03 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
Aug 06 Javascript
jquery实现的回旋滚动效果完整实例【附demo源码下载】
Sep 20 Javascript
bootstrap常用组件之头部导航实现代码
Apr 20 Javascript
JavaScript数组排序reverse()和sort()方法详解
Dec 24 Javascript
vue 实现通过手机发送短信验证码注册功能
Apr 19 Javascript
seajs和requirejs模块化简单案例分析
Aug 26 Javascript
react国际化化插件react-i18n-auto使用详解
Mar 31 Javascript
vue中的计算属性和侦听属性
Nov 06 Javascript
HTML元素拖拽功能实现的完整实例
Dec 04 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
真正的ZIP文件操作类(php)
2007/07/21 PHP
phpmyadmin3 安装配置图解教程
2012/03/29 PHP
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
2014/02/18 PHP
PHP与MYSQL中UTF8 中文排序示例代码
2014/10/23 PHP
PHP实现限制IP访问的方法
2017/04/20 PHP
PHP以json或xml格式返回请求数据的方法
2018/05/31 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
读jQuery之二(两种扩展)
2011/06/11 Javascript
jquery动态更换设置背景图的方法
2014/03/25 Javascript
js使用removeChild方法动态删除div元素
2014/08/01 Javascript
jQuery插件jPaginate实现无刷新分页
2015/05/04 Javascript
javascript通过获取html标签属性class实现多选项卡的方法
2015/07/27 Javascript
JavaScript仿支付宝密码输入框
2015/12/29 Javascript
jQuery Form 表单提交插件之formSerialize,fieldSerialize,fieldValue,resetForm,clearForm,clearFields的应用
2016/01/23 Javascript
Vuejs第九篇之组件作用域及props数据传递实例详解
2016/09/05 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
JavaScript实现倒计时跳转页面功能【实用】
2016/12/13 Javascript
JavaScript中for循环的几种写法与效率总结
2017/02/03 Javascript
详解微信小程序回到顶部的两种方式
2019/05/09 Javascript
详解微信小程序开发之formId使用(模板消息)
2019/08/27 Javascript
vue中keep-alive,include的缓存问题
2019/11/26 Javascript
Python利用pandas计算多个CSV文件数据值的实例
2018/04/19 Python
Python把csv数据写入list和字典类型的变量脚本方法
2018/06/15 Python
python中partial()基础用法说明
2018/12/30 Python
Python 3 实现定义跨模块的全局变量和使用教程
2019/07/07 Python
python保留小数位的三种实现方法
2020/01/07 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
2020/06/28 Python
基于pycharm 项目和项目文件命名规则的介绍
2021/01/15 Python
boostrap modal 闪现问题的解决方法
2020/09/01 HTML / CSS
个人考核材料
2014/05/15 职场文书
教师节倡议书
2014/08/30 职场文书
教师党员个人剖析材料
2014/09/29 职场文书
2015年世界水日活动总结
2015/02/09 职场文书
学生犯错保证书
2015/05/09 职场文书
行政撤诉申请书
2015/05/18 职场文书
六种css3实现的边框过渡效果
2021/04/22 HTML / CSS