Vue页面渲染中key的应用实例教程


Posted in Vue.js onJanuary 12, 2021

引言

在前端项目开发过程中,el-table展示的结果列使用组件形式引入,其中某些字段通过:formatter方法转码,结果栏位的字段显示/隐藏控制也使用组件形式引入,前端在控制字段显示属性时,发现码值转换及字段信息展示均有问题。

问题分析

通过阅读代码结构,发现el-table-column通过template循环生成,由于template的作用是模板占位符,可帮助我们包裹元素,但在循环过程当中,template不会被渲染到页面上。有关表格数据渲染中key的作用如下:

  • key作为一个DOM节点的标识值,结合Diff算法可以实现对节点的复用。(key相同的节点会被复用);
  • 只有当key(或其他导致isSameNode判断为false)发生改变时,才会触发节点的重新渲染。否则Vue将会复用之前的节点,通过改变节点的属性来实现节点的更新。

同时,template标签不支持:key属性,

注意: vue实例绑定的元素内部的template标签不支持v-show指令,即v-show="false"对template标签来说不起作用。但是此时的template标签支持v-if、v-else-if、v-else、v-for这些指令。

解决方法

既然template标签不支持key属性,可通过在el-table-column标签加入:key="Math.random()"属性,这个key属性是vue自带的特殊属性,主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes,依次来提升页面渲染性能。如果不更新这个key的话,显示/隐藏列的时候,部分DOM不会重新渲染,导致table变化时候内容错乱。

拓展阅读

一、key的作用

前文已经讲到,作为一个DOM节点的标识值,结合Diff算法可实现对节点的复用。(key相同的节点会被复用。)

只有当key(或其他导致isSameNode判断为false)发生改变时,才会触发节点的重新渲染。否则Vue将会复用之前的节点,通过改变节点的属性来实现节点的更新。那么,key使用id与index的区别又是什么呢?

二、key使用id与index的区别

不推荐使用index作为key,因为这种做法会导致某些节点被错误地原地复用,具体如下:

  • 性能损耗:列表渲染时会导致变动项往后的所有列表节点(内容)的更新(相当于key没发挥作用)。
  • 出现错误:某些节点在错误的位置被复用。(例如当列表项中使用到复选框时)

性能损耗

列表渲染时会导致变动项往后的所有列表节点(内容)的更新(相当于key没发挥作用)

需要注意的是,变动项往后的所有列表节点的更新本质是节点属性的更新,节点本身会被复用。

<!-- 测试代码 -->
<template>
 <div>
 <div v-for="(item, index) in arr" :key="index 或 item.id">
  {{item.data}}
 </div>
 </div>
</template>

<script>
export default {
 name: 'HelloWorld',
 data(){
 return {
  arr: Array.from({length: 10000}, (v, i) => {return {id: i, data: i}})
 }
 },
 mounted(){
 setTimeout(()=>{
  /* 
  1. this.shiftArr()	// 删除首项
  或
  2. this.unShiftArr()	// 在首部插入新项
  */
 }, 1000)
 },
 methods: {
 shiftArr(){
  this.arr.shift();
 },
 unshiftArr(){
  this.arr.unshift({id: -1, data: -1});
 }
 }
}
</script>

上边的例子很简单,就是v-for渲染一个长度为10000的列表,然后在Vue mounted 1s后,执行一个删除列表首项或在列表头插入新项,观察两种key绑定的具体页面更新开销。

页面开销使用chrome的performance选项卡来测算

删除列表首项

Vue页面渲染中key的应用实例教程

列表头 unshift 新元素

Vue页面渲染中key的应用实例教程

出现错误

某些节点在错误的位置被复用。(例如当列表项中使用到复选框时)

<!-- 测试代码 -->
<template>
 <div>
 <button @click="test">删除列表第一项</button>
 <div v-for="(item, index) in arr" :key="index 或 item.id">
  <input type="checkbox" />
  {{item.data}}
 </div>
 </div>
</template>

<script>
export default {
 name: 'HelloWorld',
 data(){
 return {
  arr: Array.from({length: 5}, (v, i) => {return {id: i, data: i}})
 }
 },
 methods: {
 test(){
  this.arr.shift();
 }
 }
}
</script>

总结

到此这篇关于Vue页面渲染中key的应用的文章就介绍到这了,更多相关Vue页面渲染key的应用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
在Vue中使用Echarts可视化库的完整步骤记录
Nov 18 Vue.js
Vue项目如何引入bootstrap、elementUI、echarts
Nov 26 Vue.js
vue element实现表格合并行数据
Nov 30 Vue.js
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
Dec 02 Vue.js
vuex Module将 store 分割成模块的操作
Dec 07 Vue.js
vue实现购物车的小练习
Dec 21 Vue.js
vue首次渲染全过程
Apr 21 Vue.js
一定要知道的 25 个 Vue 技巧
Nov 02 Vue.js
Vue h函数的使用详解
Feb 18 Vue.js
Vue OpenLayer测距功能的实现
Apr 20 Vue.js
vue实现省市区联动 element-china-area-data插件
Apr 22 Vue.js
vue postcss-px2rem 自适应布局
May 15 Vue.js
Vue项目中使用mock.js的完整步骤
Jan 12 #Vue.js
vue 页面跳转的实现方式
Jan 12 #Vue.js
Vue过滤器,生命周期函数和vue-resource简单介绍
Jan 12 #Vue.js
详解template标签用法(含vue中的用法总结)
Jan 12 #Vue.js
Vue中ref和$refs的介绍以及使用方法示例
Jan 11 #Vue.js
vue实现防抖的实例代码
Jan 11 #Vue.js
Vuex实现简单购物车
Jan 10 #Vue.js
You might like
Ha0k 0.3 PHP 网页木马修改版
2009/10/11 PHP
php输出xml格式字符串(用的这个)
2012/07/12 PHP
PHP与MongoDB简介|安全|M+PHP应用实例详解
2013/06/17 PHP
PHP封装的字符串加密解密函数
2015/12/18 PHP
jquery的键盘事件修改代码
2011/02/24 Javascript
javascript 事件处理、鼠标拖动效果实现方法详解
2012/05/11 Javascript
说说JSON和JSONP 也许你会豁然开朗
2012/09/02 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
connect中间件session、cookie的使用方法分享
2014/06/17 Javascript
js闭包所用的场合以及优缺点分析
2015/06/22 Javascript
JavaScript动态改变div属性的实现方法
2015/07/22 Javascript
jQuery拖动布局其结果保存到数据库
2015/10/09 Javascript
JavaScript对HTML DOM使用EventListener进行操作
2015/10/21 Javascript
牛叉的Jquery——Jquery与DOM对象的互相转换及DOM的三种操作
2015/10/29 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
vue2.0 axios前后端数据处理实例代码
2017/06/30 Javascript
angularjs实现猜数字大小功能
2020/05/20 Javascript
JS实现利用两个队列表示一个栈的方法
2017/12/13 Javascript
JavaScript实现微信号随机切换代码
2018/03/09 Javascript
React注册倒计时功能的实现
2018/09/06 Javascript
vue父组件给子组件的组件传值provide inject的方法
2019/10/23 Javascript
uni-app微信小程序登录授权的实现
2020/05/22 Javascript
Python从零开始创建区块链
2018/03/06 Python
python3如何将docx转换成pdf文件
2018/03/23 Python
django反向解析URL和URL命名空间的方法
2018/06/05 Python
Pytorch中实现只导入部分模型参数的方式
2020/01/02 Python
导入tensorflow:ImportError: libcublas.so.9.0 报错
2020/01/06 Python
Python实现GIF图倒放
2020/07/16 Python
香港卓悦化妆品官网:BONJOUR
2017/09/21 全球购物
英国最大的网上药品商店:Chemist Direct
2017/12/16 全球购物
精致的手工皮鞋:Shoe Embassy
2019/11/08 全球购物
如何将无状态会话Bean发布为WEB服务,只有无状态会话Bean可以发布为WEB服务?
2015/12/03 面试题
继承公证书样本
2014/04/04 职场文书
生物学专业求职信
2014/07/23 职场文书
2014年环境卫生工作总结
2014/11/24 职场文书
详解Golang如何优雅的终止一个服务
2022/03/21 Golang