El-Table 动态合并行/列单元格
excel表格可以方便的合并单元格,el-table也有类似api,有时需求需要根据数据动态合并,这时候就需要我们封装更通用的方法来实现。下面介绍根据单元格值来合并单元格的逻辑。
# ElTable已有Api
强大的elTale已经有合并行列的功能,只需要我们自己处理合并逻辑
提示
通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象。
// row 当前行数据
// column 当前列,包含一些相关属性,label property rowSpan colSpan 等等...
spanMethod({ row, column, rowIndex, columnIndex }) {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {
return [1, 2];
} else if (columnIndex === 1) {
return [0, 0];
}
}
}
# 合并行
获取到表格数据,我们先进行遍历,从而计算出需要合并的单元格坐标,即找出相同值的行。封装方法方便通过属性名指定需要合并的行。
export default {
data(){
return {
tableData: [
{id: '12987122', name: '王小虎', amount1: '234', amount2: '3.2', amount3: 10},
{id: '12987123', name: '王小虎', amount1: '165', amount2: '4.43', amount3: 12},
{id: '12987124', name: '张三', amount1: '324', amount2: '1.9', amount3: 12},
{id: '12987125', name: '赵四', amount1: '621', amount2: '2.2', amount3: 12},
{id: '12987126', name: '赵四', amount1: '539', amount2: '4.1', amount3: 15}
],
spanMap: {},
};
},
mounted(){
this.initSpanArr(this.tableData, 'name')
this.initSpanArr(this.tableData, 'amount3')
},
methods: {
spanMethod( {rowIndex, column: {property}} ){
if(this.spanMap[property]){
const _row = this.spanMap[property].spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return { // [0,0] 表示这一行不显示, [2,1]表示行的合并数
rowspan: _row,
colspan: _col,
};
}
},
initSpanArr( data, column ){
let contactDot = 0;
this.spanMap[column] = {};
this.spanMap[column].spanArr = [];
data.forEach(( item, index ) => {
if(index === 0){
this.spanMap[column].spanArr.push(1); // 第一行数据 不合并
} else {
if(item[column] === data[index - 1][column]){
this.spanMap[column].spanArr[contactDot] += 1; // 下一行,如果数据相同,合并行数加一
this.spanMap[column].spanArr.push(0);
} else{
contactDot = index;
this.spanMap[column].spanArr.push(1);
}
}
});
},
}
};
Copy
# 合并列
合并列有一些差别
- 首先,不能像合并行一样,通过数据处理得到spanArr,因为视图表格中表头顺序未知
- 其次,动态合并时,相同列的值会出现多种情况,例如三列数据中三列都相同或者任意两列相同
# 解决方案
我们直接在spanMethod里进行动态处理,动态对比相邻单元格值
首先定义需要合并的列字段,注意需要保证顺序 mergeArr: ['amount1', 'amount2', 'amount3']
spanMethod遍历单元格时,我们依次判断当前单元格之后的值是否相同,以此作为合并格数,同时判断以合并的单元格直接返回[0,0] (不渲染)
spanMethod( {row, column: {property}} ){
const index = this.mergeArr.findIndex(o => o === property)
if(index !== -1){
let colSpan = 1
// 与前一列相比,相同则不再合并,并取消展示
if(row[this.mergeArr[index]] === row[this.mergeArr[index - 1]]){
return [0, 0] // [0,0] el-table 内部处理为不渲染
}
for(let i = index; i < this.mergeArr.length; i++){
// 从当前位置查找相邻相同值
if(row[this.mergeArr[index]] === row[this.mergeArr[index + 1]]){
colSpan++
}
}
// [1,5] 从当前位置,合并1行5格
return [1, colSpan > 1 ? colSpan - 1 : 1]
}
return [1, 1];
}
下面是具体的完整实现,可打开看详细代码
Copy