当前位置: 首页 > news >正文

vue3+ts+elementui-表格根据相同值合并

代码

 <div style="height: auto; overflow: auto"><el-table ref="dataTableRef" v-loading="loading" :data="pageData" highlight-current-row border@selection-change="handleSelectionChange" :span-method="objectSpanMethod" :row-style="tableRowStyle"><el-table-column type="selection" width="55" align="center" /><!-- <el-table-column key="id" label="id" prop="id" align="center" /> --><el-table-column key="roomName" label="房间名称" prop="roomName" align="center" /><el-table-column key="categoryName" label="所属分类" prop="categoryName" align="center" /><el-table-column key="deviceName" label="设备名称" prop="deviceName" align="center" /></el-table><pagination v-if="total > 0" v-model:total="total" v-model:page="queryParams.pageNum"v-model:limit="queryParams.pageSize" @pagination="handleQuery()" style="float: right;" /></div>

js 


interface User {id: stringroomName: stringdeviceName: stringcategoryName: string
}
interface SpanMethodProps {row: Usercolumn: TableColumnCtx<User>rowIndex: numbercolumnIndex: number
}
const objectSpanMethod = ({ row, column, rowIndex }) => {if (column.property === 'roomName') {const currentRoom = row.roomName;let prevRoom = rowIndex === 0 ? null : pageData.value[rowIndex - 1].roomName;if (rowIndex === 0 || currentRoom !== prevRoom) {let count = 1;for (let i = rowIndex + 1; i < pageData.value.length; i++) {if (pageData.value[i].roomName === currentRoom) {count++;} else {break;}}return { rowspan: count, colspan: 1 };} else {return { rowspan: 0, colspan: 0 };}}if (column.property === 'categoryName') {const currentCategory = row.categoryName;let prevCategory = rowIndex === 0 ? null : pageData.value[rowIndex - 1].categoryName;if (rowIndex === 0 || currentCategory !== prevCategory) {let count = 1;for (let i = rowIndex + 1; i < pageData.value.length; i++) {if (pageData.value[i].categoryName === currentCategory) {count++;} else {break;}}return { rowspan: count, colspan: 1 };} else {return { rowspan: 0, colspan: 0 };}}return { rowspan: 1, colspan: 1 };
}
// 定义合并信息的类型
type SpanInfo = {rowspan: numbercolspan: number
}// 用于存储 roomName 和 categoryName 的合并信息
const roomNameSpanMap: Map<number, SpanInfo> = new Map() // key 是 rowIndex
const categoryNameSpanMap: Map<number, SpanInfo> = new Map()// 计算合并信息的方法
const calculateSpans = (data: User[]) => {let roomNameCount = 1let categoryNameCount = 1let prevRoomName = data[0]?.roomNamelet prevCategoryName = data[0]?.categoryName// 第一行默认 rowspan 为后续相同项的数量roomNameSpanMap.set(0, { rowspan: 1, colspan: 1 })categoryNameSpanMap.set(0, { rowspan: 1, colspan: 1 })for (let i = 1; i < data.length; i++) {const current = data[i]const prev = data[i - 1]// 处理 roomNameif (current.roomName === prev.roomName) {roomNameCount++// 当前行不显示,rowspan 设为 0roomNameSpanMap.set(i, { rowspan: 0, colspan: 0 })} else {// 新的 roomName,设置 rowspan 为累计的数量roomNameSpanMap.set(i - 1, { rowspan: roomNameCount, colspan: 1 })roomNameCount = 1 // 重置计数roomNameSpanMap.set(i, { rowspan: 1, colspan: 1 }) // 当前行可能是新的开始}// 处理 categoryNameif (current.categoryName === prev.categoryName) {categoryNameCount++categoryNameSpanMap.set(i, { rowspan: 0, colspan: 0 })} else {categoryNameSpanMap.set(i - 1, { rowspan: categoryNameCount, colspan: 1 })categoryNameCount = 1categoryNameSpanMap.set(i, { rowspan: 1, colspan: 1 })}prevRoomName = current.roomNameprevCategoryName = current.categoryName}// 处理最后一行的 rowspanroomNameSpanMap.set(data.length - 1, { rowspan: roomNameCount, colspan: 1 })categoryNameSpanMap.set(data.length - 1, { rowspan: categoryNameCount, colspan: 1 })
}
const tableRowStyle = ({ row, rowIndex }) => {return {height: '40px','vertical-align': 'middle'}
}

style 

// 表格
/* 确保表格行高一致,避免合并后行高错乱 */
:deep(.el-table .el-table__row) {/* 不要设置height/min-height/line-height,自动撑开 */vertical-align: middle !important;
}:deep(.el-table__cell) {vertical-align: middle !important;
}/* 确保表格容器有足够的空间 */
:deep(.table-container) {height: auto;/* 自动高度 */overflow: auto;/* 如果内容超出,显示滚动条 */
}

http://www.dtcms.com/a/284038.html

相关文章:

  • 宝塔面板一键迁移(外网服务器迁移到内网服务器)
  • Robin问题傅里叶变换与解分析
  • java如何实现打印list对象占用多大内存
  • 算法学习笔记:26.二叉搜索树(生日限定版)——从原理到实战,涵盖 LeetCode 与考研 408 例题
  • xss防御策略
  • 单例模式详细讲解
  • 从 0 到 1 玩转 XSS - haozi 靶场:环境搭建 + 全关卡漏洞解析
  • 50倍性能飞跃!Spring Boot+Doris Stream Load海量数据实时更新方案
  • RabbitMQ—消息可靠性保证
  • 破解本地数据库困局:DbGate+内网穿透如何实现远程管理自由
  • React Native打开相册选择图片或拍照 -- react-native-image-picker
  • CSDN首发:研究帮平台深度评测——四大AI引擎融合的创作革命
  • MySQL安全修改表结构、加索引:ON-Line-DDL工具有哪些
  • mapbox V3 新特性,添加模型图层
  • 深入GPU硬件架构及运行机制
  • OpenCV学习笔记二(色彩空间:RGB、HSV、Lab、mask)
  • 多维动态规划题解——最长公共子序列【LeetCode】空间优化:两个数组(滚动数组)
  • Python eval函数详解 - 用法、风险与安全替代方案
  • Java使用FastExcel实现模板写入导出(多级表头)
  • 设计模式四:装饰模式(Decorator Pattern)
  • maven本地仓库清缓存py脚本
  • 设计模式笔记_结构型_装饰器模式
  • centos中新增硬盘挂载文件夹
  • Install Docker Engine on UbuntuMySQL
  • 【安卓按键精灵辅助工具】adb调试工具连接安卓模拟器异常处理
  • Vuex中store
  • 爬虫核心原理与入门技巧分析
  • JavaScript中的Window对象
  • Vue3入门-组件及组件化
  • Sentinel配置Nacos持久化