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实现表格合并功能
Dec 01 Vue.js
Vue仿百度搜索功能
Dec 28 Vue.js
vue-quill-editor插入图片路径太长问题解决方法
Jan 08 Vue.js
Vue页面渲染中key的应用实例教程
Jan 12 Vue.js
Vue实现简单计算器
Jan 20 Vue.js
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
Feb 23 Vue.js
vue常用高阶函数及综合实例
Feb 25 Vue.js
使用Vue.js和MJML创建响应式电子邮件
Mar 23 Vue.js
vue首次渲染全过程
Apr 21 Vue.js
Vue接口封装的完整步骤记录
May 14 Vue.js
详解Vue的options
May 15 Vue.js
vue2的 router在使用过程中遇到的一些问题
Apr 13 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 api函数实现数组的交换排序示例
2014/04/13 PHP
php防止站外远程提交表单的方法
2014/10/20 PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
2016/03/29 PHP
基于jquery+thickbox仿校内登录注册框
2010/06/07 Javascript
jquery dialog键盘事件代码
2010/08/01 Javascript
基于Jquery的动态添加控件并取值的实现代码
2010/09/24 Javascript
js多级树形弹出一个小窗口层(非常好用)实例代码
2013/03/19 Javascript
js数组的基本用法及数组根据下标(数值或字符)移除元素
2013/10/20 Javascript
深入解析AngularJS框架中$scope的作用与生命周期
2016/03/05 Javascript
深入浅析JavaScript中的scrollTop
2016/07/11 Javascript
JS实现六边形3D拖拽翻转效果的方法
2016/09/11 Javascript
AngularJS指令中的绑定策略实例分析
2016/12/14 Javascript
JS常见算法详解
2017/02/28 Javascript
Angular.js去除页面中显示的空行方法示例
2017/03/30 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
js浏览器滚动条卷去的高度scrolltop(实例讲解)
2017/07/07 Javascript
Javascript 严格模式use strict详解
2017/09/16 Javascript
微信小程序实现两个页面传值的方法分析
2018/12/11 Javascript
vue slot与传参实例代码讲解
2019/04/28 Javascript
vue的滚动条插件实现代码
2019/09/07 Javascript
jquery实现加载更多&quot;转圈圈&quot;效果(示例代码)
2020/11/09 jQuery
Python中itertools模块用法详解
2014/09/25 Python
python实现机器学习之元线性回归
2018/09/06 Python
FFT快速傅里叶变换的python实现过程解析
2019/10/21 Python
实例代码讲解Python 线程池
2020/08/24 Python
美国男士和女士奢侈品折扣手表购物网站:Certified Watch Store
2018/06/13 全球购物
C/C++有关内存的思考题
2015/12/04 面试题
微博营销计划书
2014/01/10 职场文书
政法学院毕业生求职信
2014/02/28 职场文书
大学生交通专业求职信
2014/09/01 职场文书
无犯罪记录证明
2014/09/19 职场文书
乡党委干部党的群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
师德师风个人整改措施
2014/10/27 职场文书
学生检讨书范文
2014/10/30 职场文书
学校运动会感想
2015/08/10 职场文书
SQL实现LeetCode(176.第二高薪水)
2021/08/04 MySQL