Vue3在大数据场景下原生实现单元格合并,让Thead固定让Tbody滚动

尝试在Vue3中使用Element-plus的el-table来实现单元格合并(即rowspan/colspan)功能,在数据量很大的场景下发现有性能问题,于是用原生的方式来实现,另外,生成的表格还能实现表头固定表体滚动的功能,具体代码如下:

.vue组件代码:

<template><divclass="custom-table-wrapper"v-html="mapStore.trajectoryDetailsTable"v-loading="loading"element-loading-text="加载中..."@click="handleClick"></div>
</template><script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {getAjaxPersonnelData,getAjaxPersonnelTableData,
} from "@/api/getAjaxData.js";
import pinia from "@/store/pinia";
import { useMapStore } from "@/store/map";
const mapStore = useMapStore(pinia);let loading = ref(true);// 点击单元格时
function handleClick(event) {const target = event.target;const obj = JSON.parse(target.getAttribute("data").replace(/\n/g, "").replace(/%/g, '"'));if (obj.hasOwnProperty("personName") && !obj.hasOwnProperty("lon")) {// ...} else {if (obj.lat && obj.lon) {// ...} else {// ...}}
}onMounted(async () => {// ...
});onBeforeUnmount(() => {// ...
});
</script><style scoped>
.custom-table-wrapper {height: calc(100% - 31px) !important;overflow: auto;
}.custom-table-wrapper /deep/ .custom-table {width: 100%;border-collapse: collapse;background: linear-gradient(to right,rgba(255,255,255, 0.25),rgba(94, 182, 255, 0.35),rgba(255,255,255,0));
}.custom-table-wrapper /deep/ .custom-table thead {position: -webkit-sticky;/* Safari 支持 */position: sticky;top: 0;/* 距离顶部的位置 */z-index: 1;/* 确保表头在其他元素之上 */
}.custom-table-wrapper /deep/ .custom-table thead tr{border: 1px solid rgba(255, 255, 255, 0.1);
}.custom-table-wrapper /deep/ .custom-table thead th {border: 1px solid rgba(255, 255, 255, 0.1);background: linear-gradient(to right,rgba(255,255,255,0),rgba(94, 182, 255, 0.35),rgba(255,255,255,0));padding: 8px;color: rgba(255, 255, 255, 1);text-shadow: 1px 1px 1px #000;text-align: left;font-size: 15px;font-weight: bold;
}.custom-table-wrapper /deep/ tr:nth-child(odd) {/* background: rgba(78, 93, 110, 1); */background: linear-gradient(to right,rgba(255,255,255,0),rgba(94, 182, 255, 0.05),rgba(255,255,255,0));
}.custom-table-wrapper /deep/ tr:nth-child(even) {/* background: rgba(78, 93, 110, 1); */background: linear-gradient(to right,rgba(255,255,255,0),rgba(94, 182, 255, 0.15),rgba(255,255,255,0));
}.custom-table-wrapper /deep/ tr:nth-child(odd):hover {background: linear-gradient(to right,rgba(255,255,255,0),rgba(94, 182, 255, 0.15),rgba(255,255,255,0));cursor: pointer;
}.custom-table-wrapper /deep/ tr:nth-child(even):hover {background: linear-gradient(to right,rgba(255,255,255,0),rgba(94, 182, 255, 0.05),rgba(255,255,255,0));cursor: pointer;
}.custom-table-wrapper /deep/ .custom-table td {border: 1px solid rgba(255, 255, 255, 0.1);padding: 5px 10px;color: rgba(255, 255, 255, 1);text-shadow: 1px 1px 1px #000;word-break: break-all;word-wrap: break-word;overflow-wrap: break-word;font-size: 14px;
}
</style>

getAjaxData.js代码:

import axios from "axios";
import {ElMessage
} from "element-plus";
import "element-plus/theme-chalk/el-message.css";
import personalData from "./data.js";
import pinia from "@/store/pinia";
import {useMapStore
} from "@/store/map";
const mapStore = useMapStore(pinia);const getAjaxPersonnelData = async (obj) => {// 获取异步数据return new Promise((resolve, reject) => {setTimeout(() => {resolve(personalData);}, 1000);});
};const getAjaxPersonnelTableData = (obj) => {getAjaxPersonnelData(obj).then(res => {let tableString ='<table class="custom-table"><thead><tr><th width="100">姓名</th><th>身份证号码</th><th width="200">拍摄位置</th><th width="150">拍摄时间</th><th width="150">经度</th><th width="150">纬度</th></tr></thead><tbody>';for (let n = 0; n < res["personTrack"].length; n++) {mapStore.trajectoryNameList.push({value: res["personTrack"][n]["personName"],label: res["personTrack"][n]["personName"],});for (let m = 0; m < res["personTrack"][n]["trackList"].length; m++) {if (res["personTrack"][n]["trackList"].length === 0) {tableString += `<tr><td rowspan="${res["personTrack"][n]["trackList"].length}" data='{%personName%: %${res["personTrack"][n]["personName"]}%}'>${res["personTrack"][n]["personName"]}</td><td rowspan="${res["personTrack"][n]["trackList"].length}" data='{%personName%: %${res["personTrack"][n]["personName"]}%}'>${res["personTrack"][n]["personImageUrl"]}</td><td></td><td></td><td></td><td></td></tr>`;} else {if (m === 0) {tableString += `<tr><td rowspan="${res["personTrack"][n]["trackList"].length}" data='{%personName%: %${res["personTrack"][n]["personName"]}%}'>${res["personTrack"][n]["personName"]}</td><td rowspan="${res["personTrack"][n]["trackList"].length}" data='{%personName%: %${res["personTrack"][n]["personName"]}%}'>${res["personTrack"][n]["personImageUrl"]}</td><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}</td><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchShotTime"]}</td><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchLongitude"]}</td><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchLatitude"]}</td></tr>`;} else {tableString += `<tr><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}</td><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchShotTime"]}</td><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchLongitude"]}</td><td data='{%personName%: %${res["personTrack"][n]["personName"]}%, %lon%: ${res["personTrack"][n]["trackList"][m]["matchLongitude"]}, %lat%: ${res["personTrack"][n]["trackList"][m]["matchLatitude"]}, %matchShotTime%: %${res["personTrack"][n]["trackList"][m]["matchShotTime"]}%, %matchDevicePosition%: %${res["personTrack"][n]["trackList"][m]["matchDevicePosition"]}%}'>${res["personTrack"][n]["trackList"][m]["matchLatitude"]}</td></tr>`;}}}}tableString += "</tbody></table>";mapStore.trajectoryDetailsTable = tableString;}).catch(error => {ElMessage.error(error);});
}export {getAjaxPersonnelData,getAjaxPersonnelTableData
};

data.js数据格式:

let data = {personTrack: [{personId: 1,personNumber: "xxx",personName: "xxx",personSex: null,personImageUrl: "xxx.jpg",trackList: [{matchId: 25489,matchSimilarity: 0.953387975692749,matchCoordinatesFix: null,matchDevicePosition: "xxx",matchLongitude: x,matchLatitude: x,matchShotTime: "xxx",}],},{personId: 2,personNumber: "xxx",personName: "xxx",personSex: null,personImageUrl: "xxx.jpg",trackList: [{matchId: 25509,matchSimilarity: 0.9613999724388123,matchCoordinatesFix: null,matchDevicePosition: "xxx",matchLongitude: x,matchLatitude: x,matchShotTime: "xxx",},],}],queryInfo: {nameList: null,numberList: null,minSimilarity: 0.9,maxSimilarity: 1,startDateTime: "2024-09-14 00:00:00",endDateTime: "2024-10-14 23:59:59",},};export default data;

Pinia

pinia.js:

import { createPinia } from 'pinia';
const pinia = createPinia();
export default pinia;

map.js

// 引入defineStore用于创建store
import { defineStore } from "pinia";// 定义并暴露一个store
export const useMapStore = defineStore("defineMap", {// 动作actions: {},// 状态state() {return {trajectoryDetailsTable: "",};},// 计算getters: {},
});

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

哈工深、微信:“慢思考”超长文档翻译智能体

如今&#xff0c;大语言模型已经成为机器翻译任务&#xff08;Machine Translation&#xff09;上的新型强大工具。 然而&#xff0c;多数在机器翻译大语言模型&#xff08;MT-LLM&#xff09;上开展的研究工作都是句子层面的&#xff0c;每一句话都被独立进行翻译&#xff0c;…

训练VLM(视觉语言模型)的经验

知乎&#xff1a;lym 链接&#xff1a;https://zhuanlan.zhihu.com/p/890327005 如果可以用prompt解决&#xff0c;尽量用prompt解决&#xff0c;因为训练&#xff08;精调&#xff09;的模型往往通用能力会下降&#xff0c;训练和长期部署成本都比较高&#xff0c;这个成本也包…

vScode---配置Pyqt5环境--记录

前提条件&#xff1a; python运行环境已正常安装 1、安装Pyqt5 第三方库下载地址记录&#xff1a; 清华大学&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 豆瓣&#xff1a;https://pypi.douban.com/simple 阿里云&#xff1a;https://mirrors.aliyun.com/pypi/simpl…

一文读懂组态图和组态软件,最浅显的解读

一、什么是组态图 组态图是指在工业自动化领域中&#xff0c;用来描述和展示控制系统中各个组件之间关系和工作流程的图形化表示方法。它是一个系统的框架图&#xff0c;通过图形符号和连接线&#xff0c;将各个组件&#xff08;如传感器、执行器、控制器等&#xff09;以及它…

linux ps和kill指令

目录 ps 命令 kill指令&#xff1a; 示例&#xff1a; 补充&#xff1a;管道的概念 管道的概念 管道的用途 示例 在Linux系统中&#xff0c;ps 和 kill 是两个非常常用的命令&#xff0c;用于管理和终止进程。 ps 命令 ps 命令用于显示当前系统中的进程状态。它可以提供…

责任链模式下,解决开闭原则问题实践

前言 在现代软件工程中&#xff0c;设计模式是解决常见问题的有效工具之一。它们吸收了前人的经验&#xff0c;不仅帮助开发者编写更清晰、更可维护的代码&#xff0c;还能促进团队之间的沟通和协作。责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;作为一…

无人机+视频推流直播EasyCVR视频汇聚/EasyDSS平台在森林防护巡检中的解决方案

随着科技的飞速发展&#xff0c;无人机技术在各个领域的应用日益广泛&#xff0c;特别是在森林防护与巡检方面&#xff0c;无人机以其独特的优势&#xff0c;为传统林业管理带来了革命性的变化。本文将探讨无人机在森林防护巡检中的解决方案&#xff0c;分析其工作原理、优势及…

基于SSM+微信小程序的电子点餐管理系统(点餐1)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的电子点餐管理系统实现了管理员及用户。管理员实现了首页、个人中心、餐品分类管理、特色餐品管理、订单信息管理、用户管理、特价餐品管理、活动订单管理、系统管理。…

【论文学习与撰写】使用endnote工具进行论文参考文献的引用与插入

目录 1、软件的安装 2、放入endnote格式文献 3、endnote里文献管理 4、论文里引用参考文献的插入 5、参考文献的格式转换&#xff0c;及格式的下载 1、软件的安装 关注软件管家&#xff0c;进行下载软件和安装软件 下载通道②百度网盘丨下载链接&#xff1a; https://pa…

js.矩阵置零

链接&#xff1a;73. 矩阵置零 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],…

Flutter 11 Android原生项目集成Flutter Module

本文主要讲解如何在已有的Android原生老项目中集成Flutter模块。 实现流程&#xff1a; 1、在Android原生项目根目录下&#xff0c;创建Flutter Module&#xff1b; 2、修改Android原生项目settings.gradle&#xff0c;绑定 Flutter Module&#xff1b; 3、修改Android原生…

15分钟学Go 第6天:变量与常量

第6天&#xff1a;变量与常量 在Go语言中&#xff0c;变量和常量是编程的基础概念。理解如何定义和使用它们不仅能帮助我们管理数据&#xff0c;还能增强代码的可读性和可维护性。在本章中&#xff0c;我们将详细探讨Go语言中的变量和常量&#xff0c;涵盖它们的定义、使用、作…

[Xshell] Xshell的下载安装使用及连接linux过程 详解(附下载链接)

前言 Xshell.zip 链接&#xff1a;https://pan.quark.cn/s/5d9d1836fafc 提取码&#xff1a;SPn7 安装 下载后解压得到文件 安装路径不要有中文 打开文件 注意&#xff01;360等软件会拦截创建注册表的行为&#xff0c;需要全部允许、同意。或者退出360以后再安装。 在“绿化…

spdlog学习记录

spdlog Loggers&#xff1a;是 Spdlog 最基本的组件&#xff0c;负责记录日志消息。在 Spdlog 中&#xff0c;一个 Logger 对象代表着一个日志记录器&#xff0c;应用程序可以使用 Logger 对象记录不同级别的日志消息Sinks&#xff1a;决定了日志消息的输出位置。在 Spdlog 中&…

程序员节的故事:在代码的海洋中遨游

#1024程序员节 | 征文# 一年一度的程序员节又来了&#xff0c;作为一名热爱编程的开发者&#xff0c;我总是期待着这个特殊的日子。10月24日&#xff0c;不仅是程序员们的节日&#xff0c;更是我们分享故事、交流技术的时刻。今年的1024征文活动让我感到无比兴奋&#xff0c;因…

Axure重要元件三——中继器修改数据

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;中继器修改数据 主要内容&#xff1a;显示编辑内容、表格赋值、修改数据 应用场景&#xff1a;更新行、表单数据行修改 案例展示&#xff1a; 正文…

STM32L031F6P6基于CubeMX的串口通信调试笔记

用CubeMX创建项目 本实例用的PA14、PA13两个引脚&#xff0c;LPUART1。 对串口参数进行设置&#xff1a; 开启串口中断&#xff1a; 时钟源设置成内部高频时钟&#xff1a; 对项目进行设置&#xff1a; 生成代码&#xff1a; 在串口初始化函数中加入 __HAL_UART_ENA…

C++11 thread,mutex,condition_variable,atomic,原子操作CAS,智能指针线程安全,单例模式最简单实现方式

1.thread 在c11中&#xff0c;c标准委员会开发出了thread库&#xff1b;接下来我们先来看看这个库的使用吧&#xff1b; 1.1 thread类接口介绍 1.1.1 thread类构造函数 我们thread库中的thread类的构造函数可以通过直接传递回调函数与函数的参数来构造线程&#xff1a; int…

THP4 SOP16 芯片 高速光耦芯片

光电耦合器输入端加电信号使发光源发光&#xff0c;光的强度取决于激励电流的大小&#xff0c;此光照射到封装在一起的受光器上后&#xff0c;因光电效应而产生了光电流&#xff0c;由受光器输出端引出&#xff0c;这样就实现了电一光一电的转换。 由于光耦合器输入输出间互相…

mysql主从复制及故障修复

一、主MySQL数据库的配置 分别在三台主机&#xff08;chen2/10.110、chen3/10.120、chen4/10.130)中安装mysql数据&#xff0c;其中chen2/10.110作为主MySQL服务器&#xff0c;其余两台作为从MySQL服务器。 1、在主机上部署mysql数据库 详细的请看上一篇&#xff1a;mysql数据…