el-table中 el-popover 性能优化

场景:在 el-table 中使用 el-popover ,出现了 loading 加载卡顿的问题,接口返回的数据的时间大概是 140ms ,所以不是接口慢的原因;通过对表中结构的逐步排查,发现是表中的 某一行 所影响的;并且 其中含有 el-popover;因为 el-popover 会渲染出真实的 dom 元素 所以在页面渲染的时候会出现el-table loading 卡顿的情况。
在这里插入图片描述

原来的代码是这样的

<ElTable v-loading="loading" :data="tableData" @selection-change="handleSelectionChange" size="small"
                 show-overflow-tooltip @row-dblclick="handleViewDetail" ref="tableRef"
                 :height="tableHeight" highlight-current-row @current-change="handleCurrentRowChange"
                 :row-class-name="tableRowClassName"
                 @sort-change="sort_change"
                 :cell-style="rowClassName"
                 :row-style="{height: '30px'}"
                 :header-cell-style="headerClassName"
        >
//...
	<el-table-column prop="remark" :label="$t('common.remark')" width="100">
		<template #default="scope">
            <el-popover :visible="scope.row.visible" placement="top" trigger="click" :width="204">
              <el-input v-model="scope.row.remark" style="width: 180px;"
                        :placeholder="$t('common.email.setBlockSize')"/>
              <div style="text-align: right; margin: 16px 0 0 0;">
                <el-button size="small" text @click="() => {
                              scope.row.visible = false;
                              scope.row.remark = '';
                            }">{{ $t('common.sss16') }}
                </el-button>
                <el-button size="small" type="primary" @click="() => {
                              scope.row.visible = false;
                              setRemark(scope.row.mailId, scope.row.remark)
                            }"
                >{{ $t('common.confirm') }}
                </el-button
                >
              </div>
              <template #reference>
                <el-icon @click="scope.row.visible = true" :color="scope.row.remark ? '#40a9ff' : '#dddddd'">
                  <el-tooltip
                      v-if="scope.row.remark"
                      class="box-item"
                      :content="scope.row.remark"
                      placement="right"
                  >
                    <Memo/>
                  </el-tooltip>
                  <Memo v-else/>
                </el-icon>
              </template>
            </el-popover>
          </template>
	</el-table-column>

//...
</ElTable>

解决办法:因为每次都要渲染真实dom;所以可以将 el-popover 抽离 就像 el-dialog 一样;只不过这里有特别的地方是——每行的数据都是不一样的,还需要动态展示每行的数据。

<el-table-column prop="remark" :label="$t('common.remark')" width="100">
            <template #default="scope">
              <el-icon :ref="(el) => (refMap[`${scope.row.id}`] = el)"
                       @click="handleRef(refMap[`${scope.row.id}`], scope.row)"
                       :color="scope.row.remark ? '#40a9ff' : '#dddddd'">
                <el-tooltip
                    v-if="emailListCheckoutTarget.remark"
                    class="box-item"
                    :content="emailListCheckoutTarget.remark"
                    placement="right"
                >
                  <Memo/>
                </el-tooltip>
                <Memo v-else/>
              </el-icon>

            </template>
          </el-table-column>

抽离的 el-popover

      <el-popover
          virtual-triggering
          :virtual-ref="tempRef"
          v-model:visible="visiblePopover"
          placement="top"
          :width="204"
          trigger="click"
          :popper-options="{
              modifiers: [{
		          name: 'offset',
		          options: {
			          offset: [8, 8]
		          }
	        }]
	    }">
        <el-input v-model="emailListCheckoutTarget.remark" style="width: 180px;"
                  :placeholder="$t('common.email.setBlockSize')" @keydown.enter.native.stop="okPopover"/>
        <div style="text-align: right; margin: 16px 0 0 0;">
          <el-button size="small" text @click.stop="cancelPopover">{{ $t('common.sss16') }}
          </el-button>
          <el-button size="small" type="primary" @click.stop="okPopover"
          >{{ $t('common.confirm') }}
          </el-button
          >
        </div>
      </el-popover>

最重要的一点是,采用这种方式,会出现 重复点击该列的目标对象的时候,会出现 visiblePopover 和 trigger 不同步的问题,表现为 el-popover 闪烁一次;所以需要在用户点击的时候重置 el-popover的显隐状态

 	  //真实dom数组
		const refMap = ref([])
    //目标dom对象
    const tempRef = ref(null)
    //控制 el-popover 的显隐状态
    const visiblePopover = ref(false)
    //选中的行数据
    const emailListCheckoutTarget = ref({})
    
    //触发方法
    const handleRef = (ref, item, type) => {
      tempRef.value = ref
      //重置 el-popover 显隐状态
      visiblePopover.value = false;
      setTimeout(() => {
        visiblePopover.value = true;
      }, 200)

      emailListCheckoutTarget.value = item;
      localStorage.setItem('targetItem', JSON.stringify(item.remark))
    }

其次还要考虑到什么时候渲染指定的行内容;使用 鼠标 移入、移出 事件;

    // 这里是开始点
    const mouseEnters = throttle((row) => {
		//localStorage.getItem("targetItem") 这里是特殊处理,可以根据实际情况处理
      if (localStorage.getItem("targetItem") !== row.remark) {
        visiblePopover.value = false
      }
      if (emailListCheckoutTarget.value.remark !== '') {
        emailListCheckoutTarget.value = row;
      }
    }, 300)

    const mouseLeaves = throttle((row) => {
      if (localStorage.getItem("targetItem") === row.remark) {
        // 防止popover 消失
        visiblePopover.value = false;
      }
    }, 300)

这是两个方法:提交数据;取消提交

  const cancelPopover = () => {
      visiblePopover.value = false;
      emailListCheckoutTarget.value.remark = ''
    }

    const okPopover = () => {
	//这是提交到后端
      setRemark(emailListCheckoutTarget.value.id, emailListCheckoutTarget.value.remark)
      emailListCheckoutTarget.value = {};
      visiblePopover.value = false;
    }

经过上面的一顿操作后,肉眼可见的速度提高了,大约优化了 0.5s 左右。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/458900.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三次握手seq和ack的流程 TCP协议栈seq和ack深层理解

☆ 大家可以把想了解的问题在评论发给我?我会根据问题补充到后面 ☆ 三次握手seq和ack的流程 是的,在TCP/IP协议中,三次握手过程确实涉及到序列号(Sequence Number, 简称Seq)和确认号(Acknowledgment Number, 简称Ack)的交换。这个过程是为了建立可靠的连接,确保数据能…

推荐五本书设计+界面+导航+信息架构+JS程序

『好设计比差设计更难发现』&#xff0c;因为好设计是如此的自然&#xff0c;帮助用户轻松的完成目标&#xff0c;以至于用户根本意识不到好设计的存在。设计原则是对具象设计的抽象和总结&#xff0c;然而产品是一个整体&#xff0c;用户对整个产品的认知也是从全局到局部&…

Ubuntu软件开发环境搭建

Ubuntu软件开发环境搭建 安装VMware Tools网络桥接更新软件源常用功能配置时间同步共享文件夹双向复制粘贴终端初始大小和字体设置安装必要的工具 常用指令 安装VMware Tools 点击虚拟机->安装VMware Tools… 打开终端&#xff0c;cd到/media/用户名/VMware Tools/下&#…

嵌入式面经-ARM体系架构-ARM体系结构理论基础

ARM指令集概述 指令 能够指示处理器执行某种运算的命令称为指令 指令在内存中以机器码&#xff08;二进制&#xff09;的方式存在 每一条指令都对应一条汇编 程序是指令的有序集合 指令集 处理器能识别的指令的集合称为指令集 不同架构的处理器指令集不同&#xff08;比如…

面试宝典-【spring】

目录 1.Spring是什么 ? 2.Spring框架中的单例bean是线程安全的吗&#xff1f; 3.IOC容器是什么&#xff1f; 4.什么是依赖注入&#xff1f; 6.什么是AOP &#xff1f; 7.IOC容器初始化过程&#xff1f; 8.Bean的生命周期&#xff1f; 9.BeanFactory和FactoryBean的…

代码随想录算法训练营Day59 | 503.下一个更大元素 II、42.接雨水

503.下一个更大元素 II 这题看上去有循环似乎不好做&#xff0c;其实还是蛮简单的。只需要遍历两遍来模拟循环即可&#xff0c;遍历两边还找不到结果的遍历N遍也照样找不到结果。单调栈写法仍然与 739.每日温度 相同 vector<int> nextGreaterElements(vector<int>…

vue3+ts+element-plus实际开发之统一掉用弹窗封装

vue3tselement-plus实际开发之统一掉用弹窗封装 插槽1. 官网介绍先理解 插槽、具名插槽、 作用域插槽、动态插槽名、具名作用域插槽属性和使用方法 2. 统一调用弹窗封装dome实战- 使用场景&#xff1a;- 对el-dialog进行数据动态设置- 新建一个ts文件用于统一存放组件&#xff…

感谢Cognition公司AI程序员Devin为人类程序员提供新工作:AI驯兽师AI鼓励师AI接锅侠

讲动人的故事&#xff0c;写懂人的代码 初创公司Cognition最近推出的AI程序员Devin&#xff0c;只会给人类程序员增加3类新工作。 最近&#xff0c;初创公司Cognition告诉大家一个新闻&#xff1a;他们研发了个AI程序员&#xff0c;名叫Devin。 Devin能干这些事&#xff1a; …

四川古力未来科技抖音小店:行业标杆的崛起与未来展望

在当下这个数字化、网络化的时代&#xff0c;电商行业正以前所未有的速度迅猛发展。四川古力未来科技有限公司&#xff0c;凭借其敏锐的市场洞察力和创新精神&#xff0c;成功在抖音小店平台上崭露头角&#xff0c;成为行业内的佼佼者。今天&#xff0c;我们就来一起探讨四川古…

GEE错误——Dictionary does not contain key: VV_stdDev.

错误 ComputedObject (Error) Dictionary.get: Dictionary does not contain key: VV_stdDev. Line 39: Dictionary.get: Dictionary does not contain key: VV_stdDev. 主要解决方案是检查字典中是否包含键"VV_stdDev"的拼写是否正确。如果确保拼写正确&#xff0…

3分钟阿里云数据库购买、数据库创建和连接教程

阿里云数据库怎么使用&#xff1f;阿里云服务器网aliyunfuwuqi.com整理阿里云数据库从购买到使用全流程&#xff0c;阿里云支持MySQL、SQL Server、PostgreSQL和MariaDB等数据库引擎&#xff0c;阿里云数据库具有高可用、高容灾特性&#xff0c;阿里云提供数据库备份、恢复、迁…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的火焰与烟雾检测系统详解(深度学习模型+UI界面升级版+训练数据集)

摘要&#xff1a;本研究详细介绍了一种集成了最新YOLOv8算法的火焰与烟雾检测系统&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等早期算法进行性能评估对比。该系统能够在包括图像、视频文件、实时视频流及批量文件中准确识别火焰与烟雾。文章深入探讨了YOLOv8算法的原理&#xff0…

Marin说PCB之如何利用CATIA软件把器件的3D模型导出2D格式文件

步骤一&#xff0c;打开CATIA软件&#xff0c;找到器件的3D模型文件。 如下图所示就是SD卡的3D模型图了。 若是我们想要把这个3D模型导出我们实际需要的2D的DXF或者是DWG格式的话&#xff0c;我们应该如何操作呢? 1,文件&#xff0c;新建一个DAWING格式的文件, 2&#xff0c;新…

Fix a Tree(树的遍历,判断是否有环 并连成一颗树 )

题意翻译 对于下图中的树&#xff0c; 可以用数组表示为 [2,3,3,2]。这种可以表示树的数组&#xff08;即有效&#xff09;需要符合以下条件&#xff1a; 有且只有一个索引 r &#xff0c;符合pr​r 。其中顶点 r 是树的根。对于所有剩下的 n−1 个顶点 i 一定要有在 i 和 pi…

SpringBoot3整合Mybatis-Plus与PageHelper包冲突解决

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBoot3整合Mybatis-Plus与PageHelper包冲突解决 ⏱️ 创作时间&a…

基础:TCP是什么?

1. TCP 是什么&#xff1f; TCP&#xff08;Transmission Control Protocol 传输控制协议&#xff09; 是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由IETF的RFC 793 [1]定义。 TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互连的计算机…

AI人员入侵识别摄像机

AI人员入侵识别摄像机是一种智能监控设备&#xff0c;利用人工智能技术辨认并报警可能的入侵行为。这种摄像机利用深度学习算法实时分析监控画面&#xff0c;识别出普通行人和潜在入侵者之间的差异&#xff0c;从而更准确地预警可能发生的安全事件。 该摄像机通过对比数据库中存…

redis 缓冲区详解(性能优化缓冲区优化)

目录 前言 客户端输入缓冲区 输出缓冲区 集群缓冲区 全量复制缓冲区问题 增量复制缓冲区问题 前言 在我的《Redis 为啥那么快》这篇文章中&#xff0c;详细总结了Redis 为啥那么快。今天当我要详细阐述Redis 的缓冲区时&#xff0c;意识到应该加上Redis 的缓冲区。我们假…

CC攻击详细

CC攻击是DDoS攻击的其中一种&#xff0c;是目前应用层攻击的主要手段之一&#xff0c;相比其它的DDoS攻击CC似乎更有技术含量一些。CC攻击借助代理服务器生成指向目标系统的合法请求&#xff0c;实现伪装和DDoS。我们都有这样的体验&#xff0c;访问一个静态页面&#xff0c;即…

c++基础语法—————默认成员函数

文章目录 一、构造函数&#xff08;初始化&#xff09;1.构造函数的名称与类名相同&#xff0c;没有返回类型&#xff0c;可以有参数。2.对象实例化时&#xff0c;编译器自动调用构造函数进行初始化3.若类中没有显示定义一个用户的构造函数&#xff0c;编译器则会自动生成一个默…