教程:使用 Vue 3 和 arco 实现表格合并
1. 功能概述
本教程将介绍如何使用 Vue 3 和 arco 组件库实现表格合并功能。具体来说,我们会根据表格数据中的某个字段(如 type)对表格的某一列(如入库类型列)进行合并,同时将质检说明列合并为一列。
2. 数据准备
首先,我们需要准备一份数据示例:
import { ref, computed } from 'vue';const storageGoodsVosdata = ref([{id: 1,workOrderId: 'WO001',goodsNo: 'G001',goodsName: 'Test Product 1',skuCode: 'SKU001',skuInfo: 'Color: White; Style: Simple',quantity: 1,type: 0,typeName: 'Defective Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image1.jpg','https://example.com/image2.jpg',],outerPackagingUrls: ['https://example.com/image3.jpg','https://example.com/image4.jpg',],housekeepingDiagramUrls: ['https://example.com/image5.jpg','https://example.com/image6.jpg',],createTime: '2025-02-12 09:43:31',},{id: 2,workOrderId: 'WO001',goodsNo: 'G001',goodsName: 'Test Product 1',skuCode: 'SKU001',skuInfo: 'Color: White; Style: Simple',quantity: 1,type: 0,typeName: 'Defective Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image1.jpg','https://example.com/image2.jpg',],outerPackagingUrls: ['https://example.com/image3.jpg','https://example.com/image4.jpg',],housekeepingDiagramUrls: ['https://example.com/image5.jpg','https://example.com/image6.jpg',],createTime: '2025-02-12 09:43:31',},{id: 3,workOrderId: 'WO001',goodsNo: 'G002',goodsName: 'Test Product 2',skuCode: 'SKU002',skuInfo: 'Color: Black; Style: Modern',quantity: 1,type: 1,typeName: 'Goods Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image7.jpg','https://example.com/image8.jpg',],outerPackagingUrls: ['https://example.com/image9.jpg','https://example.com/image10.jpg',],housekeepingDiagramUrls: ['https://example.com/image11.jpg','https://example.com/image12.jpg',],createTime: '2025-02-12 09:43:31',},{id: 4,workOrderId: 'WO001',goodsNo: 'G002',goodsName: 'Test Product 2',skuCode: 'SKU002',skuInfo: 'Color: Black; Style: Modern',quantity: 1,type: 1,typeName: 'Goods Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image7.jpg','https://example.com/image8.jpg',],outerPackagingUrls: ['https://example.com/image9.jpg','https://example.com/image10.jpg',],housekeepingDiagramUrls: ['https://example.com/image11.jpg','https://example.com/image12.jpg',],createTime: '2025-02-12 09:43:31',},
]);const sortedStorageData = computed(() => {return [...storageGoodsVosdata.value].sort((a, b) => a.type - b.type);
});
3. 表格合并方法
接下来,我们定义一个 spanMethod 函数来处理表格合并逻辑:
function spanMethod({ rowIndex, columnIndex }) {if (columnIndex === 0) { // 只处理第一列(入库类型列)const arr = sortedStorageData.value;const item = arr[rowIndex];// 如果是第一行,或者当前行的类型与前一行不同if (rowIndex === 0 || arr[rowIndex - 1].type !== item.type) {// 计算当前类型的连续行数const count = arr.slice(rowIndex).findIndex(row => row.type !== item.type);return {rowspan: count === -1 ? arr.length - rowIndex : count,colspan: 1,};}// 其他行不显示return {rowspan: 0,colspan: 0,};}// 处理质检说明列(最后一列)if (columnIndex === 8) { // 质检说明列的索引if (rowIndex === 0) {return {rowspan: sortedStorageData.value.length,colspan: 1,};}return {rowspan: 0,colspan: 0,};}
}
模板部分
最后,我们在模板中使用 a-table 组件来渲染表格,并绑定数据和合并方法:
<template><a-table:data="sortedStorageData":bordered="{ cell: true }":pagination="false":span-method="spanMethod"><template #columns><a-table-column title="Incoming Type" data-index="typeName" align="center" :min-width="180"><template #cell="{ record }">{{ record.type === 1 ? 'Goods Incoming' : 'Defective Incoming' }}</template></a-table-column><a-table-columntitle="Product SKU Number"data-index="salary"align="center":min-width="180"><template #cell="{ record }">{{ record.goodsNo }}</template></a-table-column><a-table-columncell-class="custom-col"title="Product Name"data-index="goodsNo"align="center":min-width="180"><template #cell="{ record }"><div class="good-item-wrapper">{{ record.goodsName }}</div></template></a-table-column><a-table-columncell-class="custom-col"title="Quantity"data-index="goodsName"align="center":min-width="180"><template #cell="{ record }"><div class="good-item-wrapper">×{{ record.quantity }}</div></template></a-table-column><a-table-column cell-class="custom-col" title="Defective Reason" data-index="spec" align="center" :min-width="180"><template #cell="{ record }"><div class="good-item-wrapper">{{ record.type === 1 ? '--' : record.reasonCodeStr }}</div></template></a-table-column><a-table-columncell-class="custom-col"title="Logistic Receipts"data-index="quantity"align="center":min-width="180"><template #cell="{ record }"><div class="good-item-wrapper"><div v-show="record.type === 1">--</div><div style="display: flex; gap: 5px;"><a-imagev-for="item in record.logisticReceiptsUrls"v-show="record.type === 0":key="item"width="30":src="item"/></div></div></template></a-table-column><a-table-columncell-class="custom-col"title="Outer Packaging"data-index="quantity"align="center":min-width="180"><template #cell="{ record }"><div class="good-item-wrapper"><div v-show="record.type === 1">--</div><div style="display: flex; gap: 5px;"><a-imagev-for="item in record.outerPackagingUrls"v-show="record.type === 0":key="item"width="30":src="item"/></div></div></template></a-table-column><a-table-columncell-class="custom-col"title="Housekeeping Diagram"data-index="quantity"align="center":min-width="180"><template #cell="{ record }"><div class="good-item-wrapper"><div v-show="record.type === 1">--</div><div style="display: flex; gap: 5px;"><a-imagev-for="item in record.housekeepingDiagramUrls"v-show="record.type === 0":key="item"width="30":src="item"/></div></div></template></a-table-column><a-table-columncell-class="custom-col"title="Quality Inspection Note"data-index="quantity"align="center":min-width="180"><template #cell="{ record }"><div class="good-item-wrapper"><!-- 这里可以替换为实际的质检说明数据 -->质检说明</div></template></a-table-column></template></a-table>
</template><script setup>
import { ref, computed } from 'vue';
import { ATable, ATableColumn, AImage } from 'ant-design-vue';const storageGoodsVosdata = ref([{id: 1,workOrderId: 'WO001',goodsNo: 'G001',goodsName: 'Test Product 1',skuCode: 'SKU001',skuInfo: 'Color: White; Style: Simple',quantity: 1,type: 0,typeName: 'Defective Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image1.jpg','https://example.com/image2.jpg',],outerPackagingUrls: ['https://example.com/image3.jpg','https://example.com/image4.jpg',],housekeepingDiagramUrls: ['https://example.com/image5.jpg','https://example.com/image6.jpg',],createTime: '2025-02-12 09:43:31',},{id: 2,workOrderId: 'WO001',goodsNo: 'G001',goodsName: 'Test Product 1',skuCode: 'SKU001',skuInfo: 'Color: White; Style: Simple',quantity: 1,type: 0,typeName: 'Defective Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image1.jpg','https://example.com/image2.jpg',],outerPackagingUrls: ['https://example.com/image3.jpg','https://example.com/image4.jpg',],housekeepingDiagramUrls: ['https://example.com/image5.jpg','https://example.com/image6.jpg',],createTime: '2025-02-12 09:43:31',},{id: 3,workOrderId: 'WO001',goodsNo: 'G002',goodsName: 'Test Product 2',skuCode: 'SKU002',skuInfo: 'Color: Black; Style: Modern',quantity: 1,type: 1,typeName: 'Goods Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image7.jpg','https://example.com/image8.jpg',],outerPackagingUrls: ['https://example.com/image9.jpg','https://example.com/image10.jpg',],housekeepingDiagramUrls: ['https://example.com/image11.jpg','https://example.com/image12.jpg',],createTime: '2025-02-12 09:43:31',},{id: 4,workOrderId: 'WO001',goodsNo: 'G002',goodsName: 'Test Product 2',skuCode: 'SKU002',skuInfo: 'Color: Black; Style: Modern',quantity: 1,type: 1,typeName: 'Goods Incoming',reasonCode: 'R01',reasonCodeStr: 'Label/Certificate/Manual/Missing or Damaged',logisticReceiptsUrls: ['https://example.com/image7.jpg','https://example.com/image8.jpg',],outerPackagingUrls: ['https://example.com/image9.jpg','https://example.com/image10.jpg',],housekeepingDiagramUrls: ['https://example.com/image11.jpg','https://example.com/image12.jpg',],createTime: '2025-02-12 09:43:31',},
]);const sortedStorageData = computed(() => {return [...storageGoodsVosdata.value].sort((a, b) => a.type - b.type);
});
function spanMethod({ rowIndex, columnIndex }) {if (columnIndex === 0) { // 只处理第一列(入库类型列)const arr = sortedStorageData.value;const item = arr[rowIndex];// 如果是第一行,或者当前行的类型与前一行不同if (rowIndex === 0 || arr[rowIndex - 1].type !== item.type) {// 计算当前类型的连续行数const count = arr.slice(rowIndex).findIndex(row => row.type !== item.type);return {rowspan: count === -1 ? arr.length - rowIndex : count,colspan: 1,};}// 其他行不显示return {rowspan: 0,colspan: 0,};}// 处理质检说明列(最后一列)if (columnIndex === 8) { // 质检说明列的索引if (rowIndex === 0) {return {rowspan: sortedStorageData.value.length,colspan: 1,};}return {rowspan: 0,colspan: 0,};}
}
</script><style scoped>
.custom-col {/* 可以添加自定义样式 */
}.good-item-wrapper {/* 可以添加自定义样式 */
}
</style>
5. 解释
- 数据排序:使用
computed计算属性对数据进行排序,确保相同类型的数据相邻。 - 表格合并逻辑:
spanMethod函数根据列索引和行索引来决定哪些单元格需要合并。对于入库类型列,根据type字段合并相同类型的行;对于质检说明列,将所有行合并为一列。 - 模板渲染:使用
a-table组件渲染表格,并通过#columns插槽定义表格列。每个列可以通过#cell插槽自定义单元格内容。
通过以上步骤,你就可以实现一个带有合并单元格功能的表格。
6. 效果

相关文章:
教程:使用 Vue 3 和 arco 实现表格合并
1. 功能概述 本教程将介绍如何使用 Vue 3 和 arco 组件库实现表格合并功能。具体来说,我们会根据表格数据中的某个字段(如 type)对表格的某一列(如入库类型列)进行合并,同时将质检说明列合并为一列。 2. …...
Docker 常用命令基础详解(二)
四、容器操作命令 4.1 运行容器 使用docker run命令可以创建并运行一个容器,它就像是一个神奇的 “启动器”,让镜像中的应用程序在容器中运行起来。其基本语法为: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 其中,OPTIONS…...
uniapp - iconfont下载本地并且运用至项目上
1、项目中创建一个文件夹放置iconfont相关文件,例如src/assets/iconfont(名称自己定义) 2、在iconfont下载项目至本地 3、解压后把文件复制进1的文件夹中 4、修改src/assets/iconfont - iconfont.css里的font-face的src地址,修…...
【前端】自己从头实现一个gpt聊天页面
预览 最小化功能点 主界面:侧边栏会话历史、聊天窗口发送和断开。侧边栏:展示会话列表,每个会话包含多条聊天记录, 通过localstorage本地储存和恢复,会话需要重命名和删除。聊天框:区分一下发送者和回答者…...
数据结构——二叉树(2025.2.12)
目录 一、树 1.定义 (1)树的构成 (2)度 2.二叉树 (1)定义 (2)二叉树的遍历 (3)遍历特性 二、练习 1.二叉树 (1)创建二叉树…...
Vulhub靶机 ActiveMQ任意 文件写入(CVE-2016-3088)(渗透测试详解)
一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 漏洞版本:ActiveMQ在5.14.0之前的版本(不包括5.14.0) 二、访问靶机IP 8161端口 默认账户密码都是admin 1、利用bp抓包,修改为PUT方法并在fileserver…...
跟着李沐老师学习深度学习(十一)
经典的卷积神经网络 在本次笔记中主要介绍一些经典的卷积神经网络模型,主要包含以下: LeNet:最早发布的卷积神经网络之一,目的是识别图像中的手写数字;AlexNet: 是第一个在大规模视觉竞赛中击败传统计算机…...
【微软- Entra ID】Microsoft Entra ID
Microsoft Entra ID是微软提供的基于云的身份和访问管理服务。Microsoft Entra ID是一个全面的解决方案,用于管理身份、执行访问策略以及在云和本地保护您的应用程序和数据。 目录 一、查看 Microsoft Entra ID 微软Entra租户 微软Entra模式 二、比较Microsoft Entra ID与…...
Halcon相机标定
1,前言。 相机的成像过程实质上是坐标系的转换。首先空间中的点由“世界坐标系”转换到“相机坐标系”,然后再将其投影到成像平面(图像物理坐标系),最后再将成像的平面上的数据转换为图像像素坐标系。但是由于透镜的制…...
Linux 配置 MySQL 定时自动备份到另一台服务器
Linux 配置 MySQL 定时自动备份到另一台服务器 前言1、配置服务器通信1.1:配置过程 2、编写自动备份sh脚本文件3:设置定时自动执行 前言 此方案可使一台服务器上的 MySQL 中的所有数据库每天 0 点自动转储为 .sql 文件,然后将文件同步到另一…...
《安富莱嵌入式周报》第350期:Google开源Pebble智能手表,开源模块化机器人平台,开源万用表,支持10GHz HRTIM的单片机,开源CNC控制器
周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版: https://www.bilibili.com/video/BV1YPKEeyEeM/ 《安富莱嵌入式周报》第350期:Google开…...
LabVIEW与小众设备集成
在LabVIEW开发中,当面临控制如布鲁克OPUS红外光谱仪这类小众专业设备的需求,而厂家虽然提供了配套软件,但由于系统中还需要控制其他设备且不能使用厂商的软件时,必须依赖特定方法通过LabVIEW实现设备的控制。开发过程中࿰…...
无人机之无线传输技术!
一、Lightbridge和OcuSync图传技术 Lightbridge技术:这是大疆自主研发的一种专用通信链路技术,使用单向图像数据传输,类似于电视广播塔的数据传输形式。它主要采用2.4GHz频段进行传输,并且可以实现几乎“零延时”的720p高清图像传…...
移远通信边缘计算模组成功运行DeepSeek模型,以领先的工程能力加速端侧AI落地
近日,国产大模型DeepSeek凭借其“开源开放、高效推理、端侧友好”的核心优势,迅速风靡全球。移远通信基于边缘计算模组SG885G,已成功实现DeepSeek模型的稳定运行,并完成了针对性微调。 目前,该模型正在多款智能终端上进…...
rust学习一、入门之搭建简单开发环境
1、搭建开发环境(windows11) a.登录官网 一看就明白,此处略。 b.安装rustup 一看就明白,此处略。 c.安装 cargo script 或者 rust-script script cargo install cargo-script 完成后 注意:时间有一点点久。 测试 cargo s…...
FANUC机器人示教器中如何显示或关闭寄存器或IO的注释信息?
FANUC机器人示教器中如何显示或关闭寄存器或IO的注释信息? 如下图所示,我们打开一个子程序,可以看到程序中的寄存器和IO是显示注释信息的, 如果想关闭注释显示的话,怎么设置? 如下图所示,按下下一页的箭头(NEXT键), 如下图所示,点击“编辑”,在弹出的窗口中,选择“…...
在SpringBoot项目中有k8s配置,但报错
如下报错一般是你没有将k8s的config拷贝到项目里,你可以将k8s主节点的config拷贝一下到项目中。 2025-02-13 09:27:21.873 ERROR 1671 --- [.models.V1Pod-1] i.k.c.informer.cache.ReflectorRunnable : class io.kubernetes.client.openapi.models.V1Pod#Reflec…...
在springboot加vue项目中加入图形验证码
后端 首先先要创建一个CaptchaController的类,可以在下面的代码中看到 在getCaptcha的方法里面写好了生成随机的4位小写字母或数字的验证码,然后通过BufferedImage类变为图片,顺便加上了干扰线。之后把图片转为Base64编码方便传给前端 为了…...
23. AI-大语言模型
文章目录 前言一、LLM1. 简介2. 工作原理和结构3. 应用场景4. 最新研究进展5. 比较 二、Transformer架构1. 简介2. 基本原理和结构3. 应用场景4. 最新进展 三、开源1. 开源概念2. 开源模式3. 模型权重 四、再谈DeepSeek 前言 AI 一、LLM LLM(Large Language Mod…...
蓝桥杯备赛笔记(二)
这里的笔记是关于蓝桥杯关键知识点的记录,有别于基础语法,很多内容只要求会用就行,无需深入掌握。 文章目录 前言一、时间复杂度1.1 时间复杂度⭐1.2 空间复杂度1.3 分析技巧 二、枚举2.1 枚举算法介绍2.2 解空间的类型2.3 循环枚举解空间 三…...
MATLAB中的APPdesigner绘制多图问题解析?与逻辑值转成十进制
在matlab APPdesigner中绘图可以用UIAxes组件进行绘图,但是当想多张图时,只能提前绘制图像区域不方便。下面是几种办法: 为了操作可以添加Panl组件,方便操作。 1、当是要求的几个图像大小都是相同时刻采用函数: til…...
Spring Cloud-Sentinel
Sentinel服务熔断与限流 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。 官网地址:home | Sentinelhttps://sen…...
Java中使用EasyExcel
Java中使用EasyExcel 文章目录 Java中使用EasyExcel一:EasyExcel介绍1.1、核心函数导入数据导出数据 1.2、项目实际应用导入数据导出数据 1.3、相关注解ExcelProperty作用示例 二:EasyExcel使用2.1、导入功能2.2、导出功能 三:EasyExcel完整代…...
Linux中退出vi编辑器的命令
在Linux中退出vi编辑器的命令有以下几种: 保存并退出:在命令模式下,按下Esc键退出插入模式,然后输入:wq或:x,按下回车键即可保存修改并退出vi编辑器。 不保存退出:在命令模式下,按…...
建筑兔零基础自学python记录18|实战人脸识别项目——视频检测07
本次要学视频检测,我们先回顾一下图片的人脸检测建筑兔零基础自学python记录16|实战人脸识别项目——人脸检测05-CSDN博客 我们先把上文中代码复制出来,保留红框的部分。 然后我们来看一下源代码: import cv2 as cvdef face_detect_demo(…...
自定义基座实时采集uniapp日志
自定义基座实时采集uniapp日志 打测试包给远端现场(测试/客户)实际测试时也能实时看到日志了,也有代码行数显示。 流程设计 #mermaid-svg-1I5W9r1DU4xUsaTF {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid…...
【java】方法:遍历/求最大值/判断是否存在
1.遍历 public class ArrayTraversal {// 定义一个静态方法用于遍历数组并在一行上显示元素public static void printArray(int[] arr) {for (int num:arr) {// 打印数组元素,不换行System.out.print(num" ");}// 遍历结束后换行System.out.println();}p…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第六节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(ReadDataByIdentifier0x22服务) 作者:车端域控测试工程师 发布日期:2025年2月13日 关键词:UDS诊断协议、0x22服务、ReadDataByIdentifier、DID读取、ECU测试 一、服务功能…...
dedecms 开放重定向漏洞(附脚本)(CVE-2024-57241)
免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...
AI知识库 - Cherry Studio
1 引言: 最近 DeepSeek 很火啊,想必大家都知道,DeepSeek 这个开源的模型出来后,因其高质量能力和R1 的思维链引发了大家本地部署的热潮。我也不例外,本地部署了一个 14B 的模型,然后把,感觉傻傻…...
