想要实现的效果
我们在写表格的时候,经常碰见需要将相同项的单元格进行合并,以下分享我的思路;
1.方法一:先格式化数据并计算好相同项应该合并的数,在调用合并计算方法(推荐) 方
data() {
return {
tableData: [],//用来储存排序好了的数据,相同的项放在一起;
rowSpans:{},//用来储存计算相同项应该合并的单元格数
};
},
//(1)步.我们要计算出相同项要合并的单元格数,有几个相同项,就合并几个,所以rowsapn++;
// 写的乱,方法没有提出来;
watch: {
queryData: {//监听传递过来的table数据
handler(value) {
let tableData = [];//用来储存排序好了的数据,相同的项放在一起;
//_.groupBy()是分组方法,第一个参数是你要处理的数据,
//第二个是参数是计算出以什么来分组的key,这里是以 部门_姓名 相同的分组
let groups = _.groupBy(value,(item)=>{
return item.dept+"_"+item.ownerName
});
const rowSpans = {};//用来储存计算相同项应该合并的单元格数
Object.keys(groups).forEach((key)=>{
let rows = groups[key]
rows.forEach((row)=>{
tableData.push({...row})//这一步就是储存排序好了的数据,相同的项放在一起
const {dept,ownerName} = row
rowSpans[dept] = rowSpans[dept] || 0
rowSpans[dept]++;//计算相同部门应该合并的行数
rowSpans[dept+"_"+ownerName] = rowSpans[dept+"_"+ownerName] || 0
rowSpans[dept+"_"+ownerName]++//计算相同人员应该合并的行数
})
})
this.rowSpans = rowSpans
this.tableData = tableData;
},
deep: true,
// 代表在wacth里声明了queryData这个方法之后立即先去执行handler方法
immediate: true,
},
},
methods:{
//(2)步.我们要计算出相同项要合并的单元格数,有几个相同项,就合并几个,所以rowsapn++
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) { //当前用户是第二列
let currKey = row["dept"]+"_"+row["ownerName"];//当前项的key
let prevKey = rowIndex == 0 ? null : this.tableData[rowIndex-1]["dept"]+"_"+this.tableData[rowIndex-1]["ownerName"],//前一项的key
if(currKey!=prevKey){
return {
rowspan: this.rowSpans[currKey],
colspan: 1,
};
}else{
return {
rowspan: 0,
colspan: 0,
};
}
} else if (columnIndex === 0) { //当前部门是第一列
let currKey = row["dept"]
let prevKey = rowIndex == 0 ? null : this.tableData[rowIndex-1]["dept"]
if(currKey!=prevKey){
return {
rowspan: this.rowSpans[currKey],
colspan: 1,
};
}else{
return {
rowspan: 0,
colspan: 0,
};
}
}
},
},
}
2.方法二:先格式化数据并计算好相同项应该合并的数,在调用合并计算方法;
不咋推荐,因为中间有跳过已经合并的单元格,这点容易混乱;
第一步,监听数据,并格式化为相同项放在一起的格式;
setrowspans(tableData) {
// 先给所有的数据都加一个v.rowspan = 1
tableData.forEach((v) => {
v.rowspan = 1;
v.rowspanDep = 1;
});
// 双层循环
// 姓名列合并
//为了便于理解,部门和姓名合并分开计算了;
const count = tableData.length
for (let i = 0; i < count; i++) {
// 内层循环,上面已经给所有的行都加了v.rowspan = 1
// 这里进行判断
// 如果当前行的id和下一行的id相等
// 就把当前v.rowspan + 1
// 下一行的v.rowspan - 1
for (let j = i + 1; j < count; j++) {
if (tableData[i].ownerName === tableData[j].ownerName) {
tableData[i].rowspan++;
tableData[j].rowspan--;
}
}
// 这里跳过已经重复的数据
i = i + tableData[i].rowspan - 1;
}
// 部门列合并
for (let i = 0; i < tableData.length; i++) {
for (let j = i + 1; j < tableData.length; j++) {
if (tableData[i].dept === tableData[j].dept) {
tableData[i].rowspanDep++;
tableData[j].rowspanDep--;
}
}
// 这里跳过已经重复的数据
i = i + tableData[i].rowspanDep-1;
}
},