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

使用 Ant Design Vue 自定渲染函数customRender实现单元格合并功能rowSpan

使用 Ant Design Vue 自定渲染函数customRender实现单元格合并功能rowSpan

背景

在使用Ant Design Vue 开发数据表格时,我们常常会遇到需要合并单元格的需求。

比如,某些字段的值可能会在多行中重复出现,而我们希望将这些重复的单元格合并为一个单元格。

通过自定义渲染函数和数据处理来实现 rowSpan 合并。

具有共同上级菜单的单元格进行合并展示

真实环境 具有相同上级菜单的单元格进行合并
请添加图片描述

模拟数据
请添加图片描述

环境准备

表格 Table - Ant Design Vue

首先,确保你已经安装了 Ant Design Vue。如果你还没有安装,可以通过以下命令安装:

npm install ant-design-vue --save

接下来,确保在你的 Vue 项目中正确引入 Ant Design Vue:

import { Table } from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';

表格结构及需求

这里我是用假数据模拟,假设我们有一个表格,需要展示以下数据:

const items = [{ parentName: '父级菜单1', menuName: '菜单名称1', address: 'New York' },{ parentName: '父级菜单1', menuName: '菜单名称2', address: 'Los Angeles' },{ parentName: '父级菜单2', menuName: '菜单名称3', address: 'Chicago' },{ parentName: '父级菜单2', menuName: '菜单名称4', address: 'San Francisco' },{ parentName: '父级菜单3', menuName: '菜单名称5', address: 'Seattle' },
];

在这张表中,parentName 字段存在多个相同的值,我们希望对相同的 parentName 进行单元格合并操作。最终效果是:父级菜单1父级菜单2 的两行 parentName 将合并成一个单元格。

代码实现

数据处理:计算 rowSpan

为了实现合并单元格,我们需要根据相同字段的连续行数动态计算每个单元格的 rowSpan 属性。

我们将通过一个名为 processTableData 的函数来处理数据。

需要重新处理我们的源数据,将parentName相同的行rowSpan记录起来,同时将不需要展示的单元格rowSpan重置为0

表头只支持列合并,使用 column 里的 colSpan 进行设置。
表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。

const processTableData = data => {let result = [];let i = 0;while (i < data.length) {const currentItem = data[i];let rowSpan = 1;//// 计算当前 parentName 后续相同的行数while (i + rowSpan < data.length && data[i + rowSpan].parentName === currentItem.parentName) {rowSpan++;}// 为当前项设置 rowSpan,记录相同的行数量,result.push({...currentItem,rowSpan});// !!!重点!!!合并的行都需要保留,但是这些保留的单元不需要渲染,设置rowSpan为0for (let j = 1; j < rowSpan; j++) {result.push({...data[i + j],rowSpan: 0 // 后续行不需要合并});}// 跳过已经合并的行,i += rowSpan;}return result;
};
表格列配置:自定义渲染

在 Ant Design Vue 的 Table 组件中,我们可以使用 customRender 来对某列的渲染进行自定义。我们将使用 rowSpan 来控制每个单元格的合并效果。

表头只支持列合并,使用 column 里的 colSpan 进行设置。
表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。

customRender

可以和jsx进行类比,这个函数可以返回html元素结构

Function(text, record, index) {}|slot-scope

生成复杂数据的渲染函数,参数分别为当前行的,当前行数据,行索引,@return 里面可以设置表格行/列合并,可参考 表格 Table - Ant Design Vue 表格行/列合并

scopedSlots

使用 columns 时,可以通过该属性配置支持 slot-scope 的属性,如 scopedSlots: { customRender: 'XXX'}配合a-table组件插槽使用

const columns = [{title: '父级菜单',dataIndex: 'parentName',// 自定义渲染函数,和jsx类似customRender: (text, record) => {return {children: text,attrs: {// 当rowSpan的值为零时,不渲染单元格,为其它值时,进行跨行rowSpan: record.rowSpan;// 获取通过processTableData处理后的rowSpan值,注意这里小驼峰命名}};}},{title: '菜单名称',key: 'menuName',width: 220,dataIndex: 'menuName',align: 'left',// 插槽渲染scopedSlots: { customRender: 'beautiful' },ellipsis: true},{title: 'Address',dataIndex: 'address',// 插槽渲染scopedSlots: { customRender: 'beautiful' },}
];
完整代码

经过上面的步骤,我们实现最终效果

最后,我们将处理过的数据传递给 Table 组件,并在模板中进行渲染。

<template><a-table style="background-color: white" :bordered="true" :columns="columns" :dataSource="tableDataList" :rowKey="(record, index) => index"><template slot="beautiful" slot-scope="scope">{{ scope }}</template></a-table>
</template><script>
export default {components: {},data() {const items = [{ parentName: '父级菜单1', menuName: '菜单名称1', key: Math.random(), address: 'New York' },{ parentName: '父级菜单1', menuName: '菜单名称2', key: Math.random(), address: 'Los Angeles' },{ parentName: '父级菜单2', menuName: '菜单名称3', key: Math.random(), address: 'Chicago' },{ parentName: '父级菜单2', menuName: '菜单名称4', key: Math.random(), address: 'San Francisco' },{ parentName: '父级菜单3', menuName: '菜单名称5', key: Math.random(), address: 'Seattle' }];const processedData = this.processTableData(items);return {tableDataList: processedData,columns: [{title: '父级菜单',dataIndex: 'parentName',// 自定义渲染函数,和jsx类似customRender: (text, record) => {return {children: text,attrs: {rowSpan: record.rowSpan // 获取通过processTableData处理后的rowSpan值,注意这里小驼峰命名}};}},{title: '菜单名称',key: 'menuName',width: 220,dataIndex: 'menuName',align: 'left',// 插槽渲染scopedSlots: { customRender: 'beautiful' },ellipsis: true},{title: 'Address',dataIndex: 'address',scopedSlots: { customRender: 'beautiful' }}]};},methods: {processTableData(data) {let result = [];let i = 0;while (i < data.length) {const currentItem = data[i];let rowSpan = 1; //// 计算当前 parentName 后续相同的行数while (i + rowSpan < data.length && data[i + rowSpan].parentName === currentItem.parentName) {rowSpan++;}// 为当前项设置 rowSpan,记录相同的行数量,result.push({...currentItem,rowSpan});// !!!重点!!!合并的行都需要保留,但是这些保留的单元不需要渲染,设置rowSpan为0for (let j = 1; j < rowSpan; j++) {result.push({...data[i + j],rowSpan: 0 // 后续行不需要合并});}// 跳过已经合并的行,i += rowSpan;}return result;}}
};
</script>

效果展示

请添加图片描述

总结

使用自定义渲染函数,结合数据可以实现单元格合并功能。

http://www.lryc.cn/news/485550.html

相关文章:

  • 相机光学(四十四)——ALL-PD和PDAF
  • Opengl光照测试
  • OpenSIP2.4.11 向 FreeSWITCH 注册
  • 【C++】深入理解 C++ 优先级队列、容器适配器与 deque:实现与应用解析
  • Android 开发与救砖工具介绍
  • vue2和vue3:diff算法的区别?
  • 后端返回大数问题
  • vue3: ref, reactive, readonly, shallowReactive
  • 5G与4G互通的桥梁:N26接口
  • 29-Elasticsearch 集群监控
  • 利用Excel批量生成含二维码的设备管理标签卡片
  • 小米运动健康与华为运动健康在苹手机ios系统中无法识别蓝牙状态 (如何在ios系统中开启 蓝牙 相册 定位 通知 相机等功能权限,保你有用)
  • 高亮变色显示文本中的关键字
  • Javascript垃圾回收机制-运行机制(大厂内部培训版本)
  • 【jvm】一个空Object对象的占多大空间
  • 241114.学习日志——[CSDIY] [CS]数据结构与算法 [00]
  • The Planets: Earth -- 练习
  • linux逻辑卷练习
  • openai 论文Scaling Laws for Neural Language Models学习
  • __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined
  • 基于PHP技术的校园站的设计与实现
  • JVM回收机制与算法
  • 24/11/14 算法笔记 GMM高斯混合模型
  • Linux下编译安装Nginx
  • 算力100问☞第4问:算力的构成元素有哪些?
  • 安装paddle
  • 飞凌嵌入式RK3576核心板已适配Android 14系统
  • SpringBoot+MyBatis+MySQL的Point实现范围查找
  • 【Apache Paimon】-- 1 -- Apache Paimon 是什么?
  • 解决VsCode无法跳转问题