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打开其他项目页面并传入数据详解
Nov 25 Vue.js
vue表单验证之禁止input输入框输入空格
Dec 03 Vue.js
vue实现滚动鼠标滚轮切换页面
Dec 13 Vue.js
vue监听滚动事件的方法
Dec 21 Vue.js
vue+vant 上传图片需要注意的地方
Jan 03 Vue.js
vue keep-alive的简单总结
Jan 25 Vue.js
用vite搭建vue3应用的实现方法
Feb 22 Vue.js
vue 动态添加的路由页面刷新时失效的原因及解决方案
Feb 26 Vue.js
深入讲解Vue中父子组件通信与事件触发
Mar 22 Vue.js
vue打包时去掉所有的console.log
Apr 10 Vue.js
vue封装数字翻牌器
Apr 20 Vue.js
vue3.0 数字翻牌组件的使用方法详解
Apr 20 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判断上传的Excel文件中是否有图片及PHPExcel库认识
2013/01/11 PHP
php中使用session_set_save_handler()函数把session保存到MySQL数据库实例
2014/11/06 PHP
PHP 7的一些引人注目的新特性简单介绍
2015/11/08 PHP
基于CI框架的微信网页授权库示例
2016/11/25 PHP
在IIS下安装PHP扩展的方法(超简单)
2017/04/10 PHP
Laravel5.0+框架邮件发送功能实现方法图文与实例详解
2019/04/23 PHP
PHP设计模式(四)原型模式Prototype实例详解【创建型】
2020/05/02 PHP
Laravel框架集合用法实例浅析
2020/05/14 PHP
读jQuery之二(两种扩展)
2011/06/11 Javascript
js根据日期判断星座的示例代码
2014/01/23 Javascript
解决Jquery鼠标经过不停滑动的问题
2014/03/03 Javascript
jquery设置按钮停顿3秒不可用
2014/03/07 Javascript
jQuery的缓存机制浅析
2014/06/07 Javascript
让angularjs支持浏览器自动填表
2014/11/10 Javascript
JavaScript中Array的实用操作技巧分享
2016/09/11 Javascript
jQuery正则验证注册页面经典实例
2017/06/10 jQuery
AngularJS使用ng-repeat遍历二维数组元素的方法详解
2017/11/11 Javascript
vueJs实现DOM加载完之后自动下拉到底部的实例代码
2018/08/31 Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
2020/05/01 Javascript
JavaScript隐式类型转换代码实例
2020/05/29 Javascript
前端使用crypto.js进行加密的函数代码
2020/08/16 Javascript
python遍历数组的方法小结
2015/04/30 Python
浅谈Python中range和xrange的区别
2017/12/20 Python
python中subprocess批量执行linux命令
2018/04/27 Python
python与字符编码问题
2019/05/24 Python
Python如何将字符串转换为日期
2020/07/31 Python
matplotlib设置颜色、标记、线条,让你的图像更加丰富(推荐)
2020/09/25 Python
python实现文件+参数发送request的实例代码
2021/01/05 Python
HTML5新特性之用SVG绘制微信logo
2016/02/03 HTML / CSS
一级方程式赛车官方网上商店:F1 Store(支持中文)
2018/01/12 全球购物
Java如何支持I18N?
2016/10/31 面试题
2014升学宴答谢词
2014/01/26 职场文书
行政文秘岗位职责范本
2014/02/10 职场文书
个性车贴标语
2014/06/24 职场文书
Python 如何解决稀疏矩阵运算
2021/05/26 Python
Android RecyclerView实现九宫格效果
2022/06/28 Java/Android