业务需求:
因为后端返回的数据是没有做处理的数租,而设计图和需求是需要判断其中某一个字段的值来进行其他字段的一个合并效果
表格合并实现逻辑:
使用的是vue3中的elmetUlpalus
- 使用
span-method属性,返回对象{rowspan: num,colspan: 1}, - 如果需要合并第一行和第二行,那么第一行返回值为
{rowspan: 2,colspan: 1},第二行返回值:{rowspan: 2,colspan: 1} - 所以核心是设置
rowspan的值, - 通过递归的方式,判断相邻行的值是否一致:
- 判断前一行与该行值是否一致,如果一致
rowspan置为0 - 如果不等则判断下一行与该行值是否相等,如果一致则该项
rowspan的值+1,不一致则rowspan的值置为1
示例代码
<el-table :data="state.dataList" v-loading="state.loading" border ref="multipleTableDevice"
:header-cell-style="FINANCETableStyle.headerCellStyle" :span-method="objectSpanMethod"
@select="handleSelectionChange1"
@select-all="handleSelectionChange"
>
JS代码:
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
let num = 1
// 根据columnIndex判断需要判断值是否相等的字段
// standardFirstName,standardSecondName,dataItem及tableData需要改为自己的项目字段-----------重要...重要...重要...--------
if ([0, 1, 7, 2, 8, 9, 10, 11, 12].includes(columnIndex)) {
num = recursionRowSpan(row, rowIndex, 'word', state.dataList)
}
return {
rowspan: num,
colspan: 1,
};
}
// 通过递归获取单元格所占大小
let nowRowSpan = 1;
const recursionRowSpan = (row: any, rowIndex: any, str: any, data: any) => {
let num: number = 0;
// row[str] == data[rowIndex - 1][str]这个用来判断是否合并,可以改为自己的判断方法
// 判断上一行字段的值与改行值是否一致
if (nowRowSpan == 1 && rowIndex > 0 && row[str] == data[rowIndex - 1][str]) {
return 0;
}
// 判断下一行字段的值与改行值是否一致
if (rowIndex + 1 < data.length && row[str] == data[rowIndex + 1][str]) {
nowRowSpan++;
num = rowIndex + 1;
return recursionRowSpan(data[num], num, str, data);
} else {
num = nowRowSpan;
nowRowSpan = 1;
return num;
}
}
示例图片
合并后的BUG:
合并后遇到的问题:选中合并列的复选框时,其实他只是给你选中了合并列的第一条
解决方法:
通过操作dom寻找表单的数据处理完成
// 当前是选中还是取消 true 选中 false 取消
let isSelect = val.length && val.indexOf(row) > -1
// 当前显示的复选框
let arr = unique(val, 'word');
// 取当前所有选中的框的iD的全集 (过滤未被选中的)
let arrId :any= []
for(var i=0;i<arr.length;i++){
if(isSelect || (!isSelect && arr[i].word !== row.word)){
arrId.push(arr[i].word);
}
}
// 根据选中的id筛选数组
let rowArrById = state.dataList.filter(item => {
return arrId.indexOf(item.word) >-1;
});
nextTick(()=>{
state.dataList.forEach(item=>{
multipleTableDevice.value.toggleRowSelection(
item,
false
)
});
// 根据条件把指定行选中
rowArrById.forEach((item:any) => {
multipleTableDevice.value.toggleRowSelection(
item,
true
);
});
})
pingZfsh.value = rowArrById
然后完美解决合并的问题以及合并后的选着bug,希望elment能早点把这个问题解决吧