vue使用a-table设置自定义合并字段实现某字段值相同则合并行
背景:
笔者前端使用ant-design-vue,二次开发了a-table,但a-table组件的属性方法都可以用;
业务需求:物资存放在不同的仓库,显示物资统计表格,以物资分组合并显示物资名称、总数量(物资A在所有库房总数量),同时显示库房名称、地址、数量(物资A在库房1的数量)。
后端返回数据结构:
[{"sumQuantity": 100,"id": "IMilokafkwdIAmWmrlAjLX","version": 1,"materialId": "1","quantity": 0,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 13:15:00","materialName": "沙袋","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101"},{"sumQuantity": 100,"id": "D0TpUNP3oF6J8DGFVBDX1v","version": 0,"materialId": "1","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "沙袋","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋"},{"sumQuantity": 100,"id": "BRmOAec1CbeKTnnnmwefxF","version": 0,"materialId": "3","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "铁锹","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋"},{"sumQuantity": 101,"id": "JGGKndrPSaVIlvDL8tG3Ea","version": 0,"materialId": "BtjEnxJslGMG3Ns3ZMtcVi","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "C","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋"},{"sumQuantity": 101,"id": "F7GtvxU2hY8HqPHF90AMpn","version": 3,"materialId": "BtjEnxJslGMG3Ns3ZMtcVi","quantity": 1,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 13:15:00","materialName": "C","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101"},{"sumQuantity": 104,"id": "FNgj4RPi1tiGzKebbr4rar","version": 2,"materialId": "E6Sdqv1JjR4HOzExdR2pi1","quantity": 4,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 13:15:00","materialName": "物资B","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101"},{"sumQuantity": 104,"id": "KzS27athAsOGPLGviZk4OF","version": 0,"materialId": "E6Sdqv1JjR4HOzExdR2pi1","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "物资B","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋"},{"sumQuantity": 104,"id": "KQ6z4WBmWmQJPvVQE9Px2G","version": 0,"materialId": "Ki7FlrYpS9UGpQcSyeZYap","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "E","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋"},{"sumQuantity": 104,"id": "JM3W9JYTNYSItMBLxDOUBf","version": 1,"materialId": "Ki7FlrYpS9UGpQcSyeZYap","quantity": 4,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 08:44:18","materialName": "E","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101"}
]
执行this.convertData(xxxData)后的数据结构为
[{"sumQuantity": 100,"id": "IMilokafkwdIAmWmrlAjLX","version": 1,"materialId": "1","quantity": 0,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 13:15:00","materialName": "沙袋","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 2,"materialNameRowSpan": 2},{"sumQuantity": 100,"id": "D0TpUNP3oF6J8DGFVBDX1v","version": 0,"materialId": "1","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "沙袋","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 0,"materialNameRowSpan": 0},{"sumQuantity": 100,"id": "BRmOAec1CbeKTnnnmwefxF","version": 0,"materialId": "3","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "铁锹","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 1,"materialNameRowSpan": 1},{"sumQuantity": 101,"id": "JGGKndrPSaVIlvDL8tG3Ea","version": 0,"materialId": "BtjEnxJslGMG3Ns3ZMtcVi","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "C","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 2,"materialNameRowSpan": 2},{"sumQuantity": 101,"id": "F7GtvxU2hY8HqPHF90AMpn","version": 3,"materialId": "BtjEnxJslGMG3Ns3ZMtcVi","quantity": 1,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 13:15:00","materialName": "C","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 0,"materialNameRowSpan": 0},{"sumQuantity": 104,"id": "FNgj4RPi1tiGzKebbr4rar","version": 2,"materialId": "E6Sdqv1JjR4HOzExdR2pi1","quantity": 4,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 13:15:00","materialName": "物资B","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 2,"materialNameRowSpan": 2},{"sumQuantity": 104,"id": "KzS27athAsOGPLGviZk4OF","version": 0,"materialId": "E6Sdqv1JjR4HOzExdR2pi1","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "物资B","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 0,"materialNameRowSpan": 0},{"sumQuantity": 104,"id": "KQ6z4WBmWmQJPvVQE9Px2G","version": 0,"materialId": "Ki7FlrYpS9UGpQcSyeZYap","quantity": 100,"warehouseId": "IBU9sfUgWhcG0RglQB8urC","updateTime": "2025-02-28 10:51:51","materialName": "E","warehouseName": "产业园3号4栋","warehouseAddress": "产业园3号4栋","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 2,"materialNameRowSpan": 2},{"sumQuantity": 104,"id": "JM3W9JYTNYSItMBLxDOUBf","version": 1,"materialId": "Ki7FlrYpS9UGpQcSyeZYap","quantity": 4,"warehouseId": "IQotvqjOcr3IknflrjDta4","updateTime": "2025-02-28 08:44:18","materialName": "E","warehouseName": "库房1","warehouseAddress": "物流运输产业院1栋101","warehouseNameRowSpan": 1,"sumQuantityRowSpan": 0,"materialNameRowSpan": 0}
]
前端部分代码
描述:1、计算每个字段(materialName)rowSpan [使用递归计算出的materialNameRowSpan存入行记录]
2、设置组件的columns,使用customRender 参见ant-design-vue文档中Column对象 使用的 API
注意:自定义需要合并字段数组,根据顺序合并字段值相同的行
methods部分函数如下
// 获取需要合并数据的rowSpanconvertData(arr, levelIndex = 0) {const levelKey = this.sortLevelconst key = levelKey[levelIndex]// 根据不同维度重新整合数据let groupObj = this.groupBy(arr, key) || {}Object.keys(groupObj).forEach((groupKey) => {if (levelIndex < levelKey.length - 1) {groupObj[groupKey] = this.convertData(groupObj[groupKey], levelIndex + 1)}// 计算rowSpangroupObj[groupKey].forEach((item, index, arr) => {item[`${key}RowSpan`] = index === 0 ? arr.length : 0})})return Object.values(groupObj).flat()},// 根据属性分组groupBy(arr = [], key) {let obj = {}arr.forEach((item) => {const val = item[key]if (!obj[val]) {obj[val] = []}obj[val].push(item)})return obj},
a-table组件columns设置如下
const materialNameRender = (value, row, index) => {return {children: value,attrs: {rowSpan: row.materialNameRowSpan,},}
}
const sumQuantityRender = (value, row, index) => {return {children: value,attrs: {rowSpan: row.sumQuantityRowSpan,},}
}
data(){
const tableColumns = [{title: "物资名称",align: "center",dataIndex: "materialName",key: "materialName",customRender: materialNameRender,},{title: "物资数量",align: "center",dataIndex: "sumQuantity",key: "sumQuantity",customRender: sumQuantityRender,},{title: "库房库位",children: [{title: "名称",dataIndex: "warehouseName",key: "warehouseName",align: "center",},{title: "地址",dataIndex: "warehouseAddress",key: "warehouseAddress",align: "center",},{title: "数量",align: "center",dataIndex: "quantity",key: "quantity",},],},{title: "更新时间",align: "center",dataIndex: "updateTime",key: "updateTime",},]return {tableColumns,sortLevel: ["materialName", "sumQuantity", "warehouseName"],}
}
示例效果

总结
纯前端实现清洗数据+表格合并 ,关键点在于前端数据结构,获取合并列的rowSpan,配合customRender,设置变量存储合并列字段顺序数组(sortLevel),能自定义实现字段值相同的则被合并行
相关文章:
vue使用a-table设置自定义合并字段实现某字段值相同则合并行
背景: 笔者前端使用ant-design-vue,二次开发了a-table,但a-table组件的属性方法都可以用; 业务需求:物资存放在不同的仓库,显示物资统计表格,以物资分组合并显示物资名称、总数量(物资A在所有库房总数量&a…...
Docker容器日常维护常用命令大全
友情提示:本文内容由银河易创(https://ai.eaigx.com)AI创作平台deepseek-v3模型生成,文中所有命令未进行验证,仅供参考。请根据具体情况和需求进行适当的调整和验证。 引言 Docker作为当前最流行的容器化技术…...
《昇腾推理服务器+DeepSeek大模型》技术培训在图为科技成功举办
2月17日,华为政企业务团队受邀莅临图为科技深圳总部,并成功举办了一场聚焦于《昇腾推理服务器DeepSeek大模型》的专业知识培训。 此次培训活动不仅深化了双方的技术交流,更标志着昇腾AI与DeepSeek大模型的全面融合应用即将迈入实质性落地的新…...
【Java环境】配置极简描述
241220 241220 241220 Java环境配置 下载JDK 注意:最好下载 Long-Term SupportLTS,长期支持版本【目前是JDK21】 下载地址:Java Downloads | Oracle. 下载这个:x64 Installer 。 安装时,路径可改,其余无…...
DeepSeek开源周Day5: 3FS存储系统与AI数据处理新标杆
项目地址: GitHub - deepseek-ai/3FS: A high-performance distributed file system designed to address the challenges of AI training and inference workloads.GitHub - deepseek-ai/smallpond: A lightweight data processing framework built on DuckDB and…...
FastAPI系列:如何配置跨域访问(CORS)
默认情况下,FastAPI应用程序不允许来自不同来源的请求。当你有一个前端应用程序与后端API通信,并且它们托管在不同的域或端口上时,在FastAPI中允许来自不同来源的请求是一种常见的场景。这被称为CORS(跨域资源共享)&am…...
Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存
Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 目录 Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 一、简单介绍 二、简单介绍 camera 三、安装 camera 四、简单案例实现 五、关键代码 一、简单…...
【deepseek第一课】从0到1介绍 采用ollama安装deepseek私有化部署,并实现页面可视化
【deepseek第一课】从0到1介绍 采用ollama安装deepseek私有化部署,并实现页面可视化 1. ollama安装1.1 linux安装1.2 windows安装2. deepSeek支持的7种蒸馏模型2.1 蒸馏模型介绍2.2 7种模型特点2.3 安装deepseek-r1:14b模型3. openwebui图形化页面安装4. java连接大模型的三…...
【Vue3 Teleport 技术解析:破解弹窗吸附与滚动列表的布局困局】
🌟 Vue3 Teleport 技术解析:破解弹窗吸附与滚动列表的布局困局 🌍 背景:传统组件嵌套的布局之痛 在传统前端开发中,组件往往被严格限制在父级 DOM 结构中,这导致三大典型问题: 层级监禁 &…...
鸿蒙HarmonyOS 开发简介
鸿蒙开发入门教程 一、技术简介 鸿蒙操作系统(HarmonyOS)是面向万物互联时代的全场景分布式操作系统,具备分布式软总线、分布式数据管理、分布式任务调度等核心能力,能让设备间实现无缝连接与协同,为用户提供统一、流…...
VBA技术资料MF276:在集合中使用键
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…...
谈谈 Node.js 中的文件系统(fs)模块,如何进行文件读写操作?
Node.js 文件系统(fs)模块深度解析与实践指南 一、模块基础与核心能力 Node.js 的 fs 模块提供了完整的文件系统操作能力,涵盖 50 个方法,主要分为以下类型: 文件读写:基础 CRUD 操作目录操作࿱…...
Python Cookbook-2.18 从指定的搜索路径寻找文件
任务 给定一个搜索路径(一个描述目录信息的字符串),需要根据这个路径和请求的文件名找到第一个符合要求的文件。 解决方案 需要循环指定的搜索路径中的目录: import os def search_file(filename,search path,pathsepos.pathsep): """…...
安装Git(小白也会装)
一、官网下载:Git 1.依次点击(红框) 不要安装在C盘了,要炸了!!! 后面都 使用默认就好了,不用改,直接Next! 直到这里,选第一个 这两种选项的区别如…...
工学一体化教育模式的核心内涵及实践意义探究
工学一体化是一种将理论教学与实践操作深度融合的教育模式,旨在通过工作过程与学习过程的有机结合,培养具备综合职业能力和创新能力的技能人才。 一、工学一体化的核心内涵 工学一体化教学模式强调“在工作中学习、在学习中工作”,其核心在于…...
前端正则表达式完全指南:从入门到实战
文章目录 第一章:正则表达式基础概念1.1 什么是正则表达式1.2 正则表达式工作原理1.3 基础示例演示 第二章:正则表达式核心语法2.1 元字符大全表2.2 量词系统详解2.3 字符集合与排除 第三章:前端常用正则模式3.1 表单验证类3.1.1 邮箱验证3.1…...
Chromium项目相关
Chromium项目相关 Chromium 是一个开源浏览器项目,旨在为所有用户构建一种更安全、更快速、更稳定的方式来体验 Web。 自 Google 在 2008 年宣布 Chromium 项目以来,他们一直很高兴能够在开源 Web 浏览器的良好基础上进行构建,并为富 Web 平…...
自动驾驶测试场景相关概念
自动驾驶测试场景 一、概念二、分类2.1、按照场景的抽象程度可分为:功能场景、逻辑场景、具体场景。2.2.、按功能划分2.3、 按环境复杂度2.3、按场景类型 三、要素四、挑战与趋势4.1、长尾场景覆盖4.2、伦理决策测试4.3、车路协同测试4.4、联邦学习驱动…...
给小白的oracle优化工具,了解一下
有时懒得分析或语句太长,可以尝试用oracle的dbms_sqldiag包进行sql优化, --How To Use DBMS_SQLDIAG To Diagnose Query Performance Issues (Doc ID 1386802.1) --诊断SQL 性能 SET ECHO ON SET LINESIZE 132 SET PAGESIZE 999 SET LONG 999999 SET SER…...
DMA发送全部历史记录数据到串口
背景 博主参与的项目中,有个读取全部历史记录的功能,如果下位机在主程序中将全部历史记录单纯地通过串口传输会比较占用cpu资源,影响主程序中别的功能。最后商量得出以下实现方案: 定义两个发送缓冲区DMATxbuf1和DMATxbuf2&…...
基因型—环境两向表数据分析——品种生态区划分
参考资料:农作物品种试验数据管理与分析 用于品种生态区划分的GGE双标图有两种功能图:试点向量功能图和“谁赢在哪里”功能图。双标图的具体模型基于SD定标和h加权和试点中心化的数据。本例中籽粒产量的GGE双标图仅解释了G和GE总变异的53.6%,…...
电路中如何计算电容容值大小
一个例题: 【电路中电容容值是怎么算出来的?】https://www.bilibili.com/video/BV1RQ4y1c7i1?vd_source3cc3c07b09206097d0d8b0aefdf07958...
c++中迭代器和指针有什么区别?
在 C 中,迭代器和指针虽然在某些场景下有相似的行为,但它们在设计目的、功能和使用场景上有本质区别。以下是详细对比和最佳实践: 一、核心区别对比表 特征指针迭代器本质原生数据类型,直接存储内存地址类对象,抽象容…...
GPT大语言模型与搜索引擎:技术本质与应用场景的深度解析
引言 在人工智能和自然语言处理(NLP)领域,GPT(Generative Pre-trained Transformer)大语言模型和搜索引擎是两个备受关注的技术。尽管它们都涉及到信息检索和生成,但它们在技术原理、应用场景和用户体验上…...
FreeRTOS-中断管理
实验目的 创建一个队列及一个任务,按下按键 KEY1 触发中断,在中断服务函数里向队列里发送数据,任务则阻塞接 收队列数据。 实验代码 实验结果 这样就实现了,使用中断往队列的发送信息,用任务阻塞接收信息...
计算机毕业设计SpringBoot+Vue.js音乐网站(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
更换k8s容器运行时环境为docker
更换k8s容器运行时环境为docker k8s-V1.24之后容器运行时默认是containerd,若想改为熟悉的docker作为运行时,需要做以下操作 在每个节点安装containerd、docker; 每个节点安装cri-docker; 调整kubelet配置并重启验证。 1.安装docker、con…...
知识图谱-资源网
知识图谱-资源网 http://openkg.cn/datasets-type/https://www.ownthink.com/knowledge.html...
CTF-web: Rust 的过程宏
Rust 的过程宏(Procedural Macros)是一种强大的元编程工具,允许你在编译时对代码进行操作和生成。与属性宏和派生宏不同,过程宏可以接收并处理任意 Rust 代码,生成新的代码片段。这里有一个简单的例子来说明 Rust 的过…...
小程序Three Dof识别 实现景区AR体验
代码工程 GitCode - 全球开发者的开源社区,开源代码托管平台 dof...
