el-table 列表单元格的合并操作实现及封装
需求:后台页面中需要对某些行的展示做单元格合并的操作,后台的列表组件主要用了Element UI-Plus 的el-table。
思路:
- 拿到接口数据(业务中后端返回的接口数据是树型结构的,故需先做一步扁平化的操作)
- 对扁平化后的数据做一次合并的预处理操作(不懂的小伙伴,可以把预处理后的数据(是一个数组)打印出来看一下就能懂了)
- 根据el-table提供的span-method方法对数据进行合并的操作
代码:
- 拿到接口数据(业务中后端返回的接口数据是树型结构的,故需先做一步扁平化的操作)根据业务实际需求修改
// 临时写的,不具备通用性需根据实际业务修改
function extendTreeData(treeArr) {
return treeArr.reduce((acc, cur, index) => {
const { list } = cur;
return acc.concat(list.map((item) => ({
...item, ...cur, rowId: index + 1,
})));
}, []);
}
- 对扁平化后的数据做一次合并的预处理操作(不太明白的小伙伴,可以把预处理后的数据(是一个数组)打印出来看一下就能懂了)
/**
* 列表行合并的预处理
* 已经封装好了,可以放全局引用
* @param {Array} tableData 表单数据
* @param {String} mergeId 合并的依据,一般是id
* @returns {Array} 处理后的合并数组
*/
export function tagRowSpan(tableData, mergeId) {
const tagArr = [];
let pos = 0;
tableData.map((_, index) => {
if (index === 0) {
tagArr.push(1);
pos = 0;
} else if (tableData[index][mergeId] === tableData[index - 1][mergeId]) {
// 合并项目
tagArr[pos] += 1;
tagArr.push(0);
} else {
tagArr.push(1);
pos = index;
}
});
return tagArr;
}
- 根据el-table提供的span-method方法对数据进行合并的操作
/**
* 实际表格合并的逻辑
* @param {Number} rowIndex 表格数据行下标
* @param {Number} columnIndex 表格数据列下标
* @param {Array} tagArr 预处理后的数组
* @param {Array} needMergeCol 需要合并的列下标
* @returns {Object}
*/
export function handleSpanMethod({ rowIndex, columnIndex }, tagArr, needMergeCol) {
if (needMergeCol.includes(columnIndex)) {
const _row = tagArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
}
- 页面的使用,方法传参详情的注释都写在第二、三点方法上部
// 写在el-table页面组件上的代码
<el-table
v-loading="tableData.isLoading"
:data="tableData.data"
:span-method="(param) => handleSpanMethod(param, tableData.spanArr, tableData.needMergeCol)"
>
// 表格列表内容
</el-table>
// 方法引用
import { tagRowSpan, handleSpanMethod } from '@/utils/form-methods';
// 表格table数据
const tableData = reactive({
data: [],
spanArr: [],
needMergeCol: [0, 1, 2, 3, 6, 9, 11], // 需要合并的表格列数
total: 0,
isLoading: false,
});
async function getTableData() {
try {
saveSearchQuery();
tableData.isLoading = true;
const resultData = await workOverviewList(searchForm);
tableData.total = resultData.data.total;
tableData.data = extendTreeData(resultData.data.list);
// 传入扁平化后的数据,以及根据什么字段来进行合并(一般是id)
tableData.spanArr = tagRowSpan(tableData.data, 'levelTwoId');
} catch (error) {
console.log(error);
} finally {
tableData.isLoading = false;
}
}