Antd Table 分页条件下的动态数据合并单元格

Antd Table 分页条件下的动态数据合并单元格

本文介绍 Ant Design Vue 的 a-table 表格组件 如何在分页条件下的对动态数据合并单元格。

1.表格组件 API

1.1 Table

参数 说明 类型 默认值
bordered 是否展示外边框和列边框 boolean false
columns 表格列的配置描述 array -
dataSource 数据数组 any[]
pagination 分页器,参考配置项pagination文档,设为 false 时不展示和进行分页 object

1.2 事件

事件名称 说明 回调参数
change 分页、排序、筛选变化时触发 Function(pagination, filters, sorter, { currentDataSource })

1.3 Column

列描述数据对象,是 columns 中的一项,Column 使用相同的 API。

参数 说明 类型 默认值
colSpan 表头列合并,设置为 0 时,不渲染 number
dataIndex 列数据在数据项中对应的 key,支持 a.b.c 的嵌套写法 string -
title 列头显示文字 string|slot -
customRender 生成复杂数据的渲染函数,参数分别为当前行的值、当前行数据、行索引,@return 里面可以设置表格行/列合并,可参考 demo 表格行/列合并 Function(text, record, index) {}|slot-scope -

1.4 pagination

分页的配置项。

参数 说明 类型 默认值
position 指定分页显示的位置 ‘top’ | ‘bottom’ | ‘both’ ‘bottom’

1.5 表格行/列合并

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

2.基础环境搭建

这里我们以 vue2 环境为例进行演示。

创建 vue2 项目:

vue create antd-demo

安装 axios:

npm install axios

安装 ant-design-vue:

# 注意这里需要指定版本,因为最新版本与 vue2 不兼容,是面向 vue3 的
npm i --save ant-design-vue@1.7.2

找到 vue.config.js 文件,将 module.exports 中的配置属性 lintOnSave 的值设置为 false,关闭 eslint 的严格语法检测。

image-20241014013529090

找到 main.js 文件,修改内容如下:

import Vue from 'vue'
import App from './App.vue'
import Antd from 'ant-design-vue';
// 注意:如果使用的 vue3,则应该引入 reset.css 而不是 antd.css
import 'ant-design-vue/dist/antd.css';

Vue.config.productionTip = false
Vue.use(Antd);
new Vue({
   
  render: h => h(App),
}).$mount('#app')

3.案例背景

我们将以一个商品采购信息的展示为例。需要注意,在同一天有多条采购记录,在一条采购记录中可能存在对不同店铺的采购。

从后端发送请求获取的 JSON 数据的数据结构是一个数组,包含多个对象。每个对象代表一条的采购记录,包含以下字段:

  1. date:字符串类型,表示记录的日期。
  2. storeList:数组类型,包含多个店铺的采购信息。

每个店铺的采购信息是一个对象,包含以下字段:

  • storeName:字符串类型,表示店铺的名称。
  • productList:数组类型,包含多个商品的采购信息。

每个商品的采购信息是一个对象,包含以下字段:

  • productName:字符串类型,表示商品的名称。
  • count:整数类型,表示该商品的采购数量。

在商品采购案例中,这个数据格式可以用于记录不同日期、不同店铺和不同商品的采购数量,便于进行库存管理和数据分析。例如,可以通过这个数据格式了解到旗舰店在 2024-10-14 这一天采购了哪些商品,各商品的数量是多少,以及分店 1 在同一天的采购情况。同样,也可以了解到 2024-10-15 这一天的采购情况。

为了简单期间,我们将需要从后端发送请求获取的 JSON 数据直接从本地文件获取,存放在 public 目录下的 data.json 新建文件中。以下示例数据你值得一看,更直观理清这个数据结构。

[
    {
   
        "date": "2024-10-14",
        "storeList": [
            {
   
                "storeName": "旗舰店",
                "productList": [
                    {
   
                        "productName": "商品A",
                        "count": 150
                    },
                    {
   
                        "productName": "商品B",
                        "count": 200
                    },
                    {
   
                        "productName": "商品C",
                        "count": 250
                    },
                    {
   
                        "productName": "商品D",
                        "count": 300
                    },
                    {
   
                        "productName": "商品E",
                        "count": 350
                    }
                ]
            },
            {
   
                "storeName": "分店1",
                "productList": [
                    {
   
                        "productName": "商品F",
                        "count": 100
                    },
                    {
   
                        "productName": "商品G",
                        "count": 250
                    },
                    {
   
                        "productName": "商品H",
                        "count": 200
                    },
                    {
   
                        "productName": "商品I",
                        "count": 150
                    }
当我们在 Vue 中使用 Ant DesignTable 组件并且面临数据量大的情况需要单元合并的时候,可以采取一些策略来优化性能并保证展示效果。 ### 实现步骤: #### 1. 自定义列渲染函数 为了支持复杂的表功能如单元合并,在 `columns` 配置项中自定义 `customRender` 函数。通过该函数判断当前行是否应该与前一行或后一行内容相同的字段进行合并,并设置相应的 colspan 和 rowspan 属性。 ```javascript const columns = [ { title: '姓名', dataIndex: 'name', customRender: ({ text, record, index }) => ({ children: text, attrs: getRowSpan('name', data, index) // 计算跨行数 }) }, ... ]; ``` 其中 `getRowSpan()` 是一个辅助方法用于计算指定字段在同一列内连续相等值的数量,以此确定每个单元应占据多少行的高度。 #### 2. 控制分页加载 对于大量数据的情况,直接一次性将所有记录显示出来不仅会影响页面响应速度还可能导致浏览器崩溃。因此推荐采用分页的方式来限制每一页的数据条目数目。Antd 提供了内置的 Pagination 组件可以直接集成到表头右下角位置,默认开启即可满足大部分场景需求;如果业务上对翻页交互有特殊要求,则可通过配置 `pagination` 参数来自定义更多细节。 另外也可以考虑启用虚拟滚动特性,仅渲染可视区域内的元素,从而进一步提升效率。 #### 示例代码片段 (简化版) 这里给出一段简单的示例说明如何结合上述两点建议处理大数据集下的单元合并问题: ```html <template> <a-table :dataSource="data" :columns="columns" rowKey="id"></a-table> </template> <script setup lang="ts"> import { ref } from "vue"; // 模拟获取远程 API 返回的大规模用户列表信息... let rawData = Array.from({ length: 50 }, (_, i) => ({ id: i + "", name: ["张三", "李四"][i % 2], // 简化起见只有两位同事轮流值班 })); function computeSpans(arr, key){ let count=1; return arr.map((item,i)=>{ if(item[key]===arr[i+1]?.[key])count++; else{ const res={...item}; Object.defineProperty(res,'span',{value:count}); count=1; return res; } }).filter(({span})=>!!span); } const data = ref(computeSpans(rawData,"name")); const columns=[ {title:"序号",customRender:(text,record,index)=>index}, {title:'员工姓名', dataIndex:'name'}, ] </script> ``` 注意上面的例子只是展示了基本思路,实际项目里你需要根据具体的业务逻辑调整算法部分以及界面布局样式等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是谢添啊

感谢你的支持,我会继续加油的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值