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 tags 创建缓存导航的过程实现
Dec 03 Vue.js
对vue生命周期的深入理解
Dec 03 Vue.js
vue使用exif获取图片经纬度的示例代码
Dec 11 Vue.js
vue3自定义dialog、modal组件的方法
Jan 04 Vue.js
vue 组件基础知识总结
Jan 26 Vue.js
如何封装Vue Element的table表格组件
Feb 06 Vue.js
Vue全家桶入门基础教程
May 14 Vue.js
vue 实现上传组件
May 31 Vue.js
vue3获取当前路由地址
Feb 18 Vue.js
前端vue+express实现文件的上传下载示例
Feb 18 Vue.js
Vue的生命周期一起来看看
Feb 24 Vue.js
VUE之图片Base64编码使用ElementUI组件上传
Apr 09 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
提高PHP编程效率 引入缓存机制提升性能
2010/02/15 PHP
php数据库连接时容易出错的特殊符号问题
2010/09/01 PHP
php简单的留言板与回复功能具体实现
2014/02/19 PHP
ECMall支持SSL连接邮件服务器的配置方法详解
2014/05/19 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(五)
2014/06/23 PHP
微信获取用户地理位置信息的原理与步骤
2015/11/12 PHP
php array_multisort 对数组进行排序详解及实例代码
2016/10/27 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
2017/06/09 PHP
怎么用javascript进行拖拽
2006/07/20 Javascript
js玩一玩WSH吧
2007/02/23 Javascript
jquery选择器的选择使用及性能介绍
2013/01/16 Javascript
JavaScript实现为input与textarea自定义hover,focus效果的方法
2015/08/21 Javascript
Bootstrap 最常用的JS插件系列总结(图片轮播、标签切换等)
2016/07/14 Javascript
jQuery下拉菜单的实现代码
2016/11/03 Javascript
Node之简单的前后端交互(实例讲解)
2017/11/14 Javascript
使用mock.js随机数据和使用express输出json接口的实现方法
2018/01/07 Javascript
React Native日期时间选择组件的示例代码
2018/04/27 Javascript
微信小程序整个页面的自动适应布局的实现
2020/07/12 Javascript
[03:56]还原FTP电影首映式 DOTA2群星拼出遗迹世界
2014/03/26 DOTA
Python高效编程技巧
2013/01/07 Python
python+django快速实现文件上传
2016/10/24 Python
Django实现的自定义访问日志模块示例
2017/06/23 Python
利用Tkinter(python3.6)实现一个简单计算器
2017/12/21 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
python里运用私有属性和方法总结
2019/07/08 Python
pytorch加载自定义网络权重的实现
2020/01/07 Python
Python读写csv文件流程及异常解决
2020/10/20 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
运动会解说词50字
2014/01/18 职场文书
考博专家推荐信
2014/05/10 职场文书
公司委托书格式
2014/08/01 职场文书
个人工作表现评价材料
2014/09/21 职场文书
2016情人节宣传语
2015/07/14 职场文书
Python预测分词的实现
2021/06/18 Python
SpringBoot中HttpSessionListener的简单使用方式
2022/03/17 Java/Android
baselines示例程序train_cartpole.py的ImportError
2022/05/20 Python