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 相关文章推荐
Vue3配置axios跨域实现过程解析
Nov 25 Vue.js
vuex Module将 store 分割成模块的操作
Dec 07 Vue.js
vue从后台渲染文章列表以及根据id跳转文章详情详解
Dec 14 Vue.js
vue 在服务器端直接修改请求的接口地址
Dec 19 Vue.js
vue 实现图片懒加载功能
Dec 31 Vue.js
Vuex实现简单购物车
Jan 10 Vue.js
详解vue之自行实现派发与广播(dispatch与broadcast)
Jan 19 Vue.js
详解Vue.js 可拖放文本框组件的使用
Mar 03 Vue.js
Vue项目中如何封装axios(统一管理http请求)
May 02 Vue.js
Vue + iView实现Excel上传功能的完整代码
Jun 22 Vue.js
教你部署vue项目到docker
Apr 05 Vue.js
Vue OpenLayer 为地图绘制风场效果
Apr 24 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 curl获取301或302转向的网址问题的解决方法
2011/06/02 PHP
推荐5款跨平台的PHP编辑器
2014/12/25 PHP
php异常处理捕获错误整理
2019/09/23 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
2019/12/25 PHP
jquery创建div 实现代码
2009/04/27 Javascript
javascript下4个跨浏览器必备的函数
2010/03/07 Javascript
js 文本滚动效果的实例代码
2013/08/17 Javascript
javascript 密码框防止用户粘贴和复制的实现代码
2014/02/17 Javascript
HTML页面弹出居中可拖拽的自定义窗口层
2014/05/07 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
jQuery的文档处理程序详解
2016/05/10 Javascript
Bootstrap布局方式详解
2016/05/27 Javascript
JavaScript实现九九乘法表的简单实例
2016/06/07 Javascript
jQuery的事件预绑定
2016/12/05 Javascript
vue router-link传参以及参数的使用实例
2017/11/10 Javascript
Vue.js与 ASP.NET Core 服务端渲染功能整合
2017/11/16 Javascript
Vue如何实现响应式系统
2018/07/11 Javascript
解决vue接口数据赋值给data没有反应的问题
2018/08/27 Javascript
详解微信小程序动画Animation执行过程
2020/09/23 Javascript
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
实例讲解Python的函数闭包使用中应注意的问题
2016/06/20 Python
R语言 vs Python对比:数据分析哪家强?
2017/11/17 Python
Flask框架响应、调度方法和蓝图操作实例分析
2018/07/24 Python
对python中的six.moves模块的下载函数urlretrieve详解
2018/12/19 Python
Python字符串匹配之6种方法的使用详解
2019/04/08 Python
Python 爬取必应壁纸的实例讲解
2020/02/24 Python
Django操作session 的方法
2020/03/09 Python
在网络中有两台主机A和B,并通过路由器和其他交换设备连接起来,已经确认物理连接正确无误,怎么来测试这两台机器是否连通?如果不通,怎么来判断故障点?怎么排
2014/01/13 面试题
中医临床专业自我鉴定范文
2014/01/15 职场文书
八项规定整改方案
2014/10/01 职场文书
教师求职简历自我评价
2015/03/10 职场文书
女性健康讲座主持词
2015/07/04 职场文书
部门主管竞聘书
2015/09/15 职场文书
《红领巾真好》教学反思
2016/02/16 职场文书
纯CSS3实现div按照顺序出入效果
2021/07/15 HTML / CSS
让JavaScript代码更加精简的方法技巧
2022/06/01 Javascript