一:先说需求
在前端页面开发中,使用AntDesignVue里面的 a-table 单元表格时,会经常遇到一样的数据:
例如下图:
此时领导会提需求,要把一样的单元格数据 合并成 一个单元格。。。
合并成这个样子:
二:开始干活
第一步:先来测式demo代码,可直接复制到自己的项目查看。
<template>
<a-table :columns="columns" :data-source="dataList" bordered> </a-table>
</template>
<script setup>
import { ref, onMounted } from 'vue';
// 数据列表
const dataList = ref([]);
// 测试数据
let testData = [
{
id: '1',
name: '哈哈',
age: 32,
phone: 18889898989,
address: '北京市',
},
{
id: '2',
name: '恩恩',
phone: 18889898888,
age: 42,
address: '北京市',
},
{
id: '3',
name: '哦哦',
age: 32,
phone: 18900010002,
address: '广州市',
},
{
id: '4',
name: '嘻嘻',
age: 18,
phone: 18900010002,
address: '广州市',
},
{
id: '5',
name: '呵呵',
age: 18,
phone: 18900010002,
address: '北京市',
},
];
// 表格头配置
const columns = [
{
title: '名字',
dataIndex: 'name',
},
{
title: '年龄',
dataIndex: 'age',
},
{
title: '手机',
dataIndex: 'phone',
},
{
title: '地址',
dataIndex: 'address',
},
];
// 获取数据
const getDataList = () => {
dataList.value = testData;
}
onMounted(() => {
getDataList();
})
</script>
测式demo运行结果:
第二步:上解决方案
其实就是写了一个处理函数;
完整代码如下:
可直接复制到自己的项目查看效果
<template>
<a-table :columns="columns" :data-source="dataList" bordered> </a-table>
</template>
<script setup>
import { ref, onMounted } from 'vue';
// 数据列表
const dataList = ref([]);
// 测试数据
let testData = [
{
id: '1',
name: '哈哈',
age: 32,
phone: 18889898989,
address: '北京市',
},
{
id: '2',
name: '恩恩',
phone: 18889898888,
age: 42,
address: '北京市',
},
{
id: '3',
name: '哦哦',
age: 32,
phone: 18900010002,
address: '广州市',
},
{
id: '4',
name: '嘻嘻',
age: 18,
phone: 18900010002,
address: '广州市',
},
{
id: '5',
name: '呵呵',
age: 18,
phone: 18900010002,
address: '北京市',
},
];
// 表格头配置
const columns = [
{
title: '名字',
dataIndex: 'name',
},
{
title: '年龄',
dataIndex: 'age',
// 合并单元格
customCell: (record, rowIndex, column) => {
// record当前行数据 rowIndex当前行索引 column当前表头
return {
rowSpan: record.ageRowSpan
}
},
},
{
title: '手机',
dataIndex: 'phone',
},
{
title: '地址',
dataIndex: 'address',
},
];
// 合并单元格的函数
const combineRowSpanFn = (key) => {
let arr = dataList.value.reduce((result, item) => {
if (result.indexOf(item[key]) < 0) {
result.push(item[key])
}
return result
}, [])
.reduce((result, keys) => {
const children = dataList.value.filter((item) => item[key] === keys);
result = result.concat(
children.map((item, index) => ({
...item,
[`${key}RowSpan`]: index === 0 ? children.length : 0
}))
)
return result
}, [])
dataList.value = arr
};
// 获取数据
const getDataList = () => {
dataList.value = testData;
}
onMounted(() => {
getDataList();
combineRowSpanFn('age'); // 使用需要合并的参数
// combineRowSpanFn('phone'); // 使用需要合并的参数
// combineRowSpanFn('address'); // 使用需要合并的参数
})
</script>
页面显示结果:很完美!
三:重点函数解析
①:最重要的其实就是这个函数:
// 合并单元格的函数
const combineRowSpanFn = (key) => {
let arr = dataList.value.reduce((result, item) => {
if (result.indexOf(item[key]) < 0) {
result.push(item[key])
}
return result
}, [])
.reduce((result, keys) => {
const children = dataList.value.filter((item) => item[key] === keys);
result = result.concat(
children.map((item, index) => ({
...item,
[`${key}RowSpan`]: index === 0 ? children.length : 0
}))
)
return result
}, [])
dataList.value = arr
};
②:在 onMounted钩子里面 获取完数据后执行此函数,传的参数就是你需要合并此列的标识
onMounted(() => {
getDataList(); // 获取数据列表
combineRowSpanFn('age'); // 使用需要合并的参数
// combineRowSpanFn('phone'); // 使用需要合并的参数
// combineRowSpanFn('address'); // 使用需要合并的参数
})
③:在columns里面进行配置customCell属性:
{
title: '年龄',
dataIndex: 'age',
// 合并单元格
customCell: (record, rowIndex, column) => {
// record当前行数据 rowIndex当前行索引 column当前表头
// record里面会有一个ageRowSpan属性
return {
rowSpan: record.ageRowSpan
}
},
},
customCell 属性 AntDesignVue 官网解释太模糊了。很难研究透彻。。。
四:注意事项
注意一: 这个函数在使用的时候会重新给表格的数据重新排列,不在乎数据顺序的可以使用。
注意二:合并一两列数据还是没有问题的,要是合并复杂的表格会出现乱码情况,超过三个或者多个它会不知道怎么排序,会导致混乱,请谨慎使用。
例如:下图就是我想把年龄、手机、地址三列数据都想合并,此时数据混乱了。
具体原因可能是源数据太乱,中间穿插不一致的太多导致,这是我的猜想。
如果有用到的可以研究一下!