首先是先封装一个方法
/**
* @description: 返回表格列合并的数组
* @param {Object} tableData data 列表数据
* @param {String} itemProperty 要合并的属性依据
*/
export function getSpanArr(tableData, itemProperty) {
if (tableData.length === 0) {
return false;
}
const spanArr = [];
let pos;
for (let i = 0; i < tableData.length; i++) {
if (i === 0) {
spanArr.push(1);
pos = 0;
} else {
// 判断当前元素与上一个元素是否相同 相同则加 1
if (tableData[i][itemProperty] && tableData[i][itemProperty] === tableData[i - 1][itemProperty]) {
spanArr[pos] += 1;
spanArr.push(0);
} else {
spanArr.push(1);
pos = i;
}
}
}
return {
spanArr: spanArr,
};
}
紧接着进行数据处理
const spanObj = ref({}); // 合并的数据对象
// 列合并渲染处理,需要合并哪个列,就在哪个列传入 。显然 checkbox 在这里无法在这里控制,我们只能通过操作dom 来实现
const renderContent = ({ text, index }: any) => {
const obj = {
children: text,
props: {} as any,
};
const spanArr = spanObj.value.spanArr;
const _row = spanArr[index];
obj.props.rowSpan = _row;
return obj;
};
const columns = [
{
title: '考试场次',
dataIndex: 'sessionId',
customRender: renderContent,
},
{
title: '考试科目',
dataIndex: 'subjectId_dictText',
}
];
// 本数据是通过 sessionId 作为唯一的标识
// 处理需要合并的列以及需要合并几个列
const dataObj = getSpanArr(startLeaseDataList.value, 'sessionId');
spanObj.value = dataObj;
但是前面的选择框并没有被合并,所以还需要继续处理
// 合并表格前面的 checkbox
nextTick(() => {
if (startLeaseDataList.value.length <= 0) {
return false;
}
var tableContent = document.getElementById('tableContent');
const tableBody = tableContent?.getElementsByClassName('ant-table-tbody');
const tr = tableBody[0].getElementsByTagName('tr');
const cellMegetList = dataObj.spanArr;
const trList = Array.from(tr);
const newTrList = trList.filter((item, index) => {
return index > 0;
});
newTrList.forEach((item, index) => {
if (cellMegetList[index] === 0) {
item.childNodes[1].setAttribute('style', 'display: none');
} else {
item.childNodes[1].setAttribute('rowspan', cellMegetList[index]);
}
});
});
值得注意的是:数据源要静态的,或者组件传值过来,当前页面中请求不太行