想要实现的效果

element列表合并单元格列 element合并单元格table_element列表合并单元格列

我们在写表格的时候,经常碰见需要将相同项的单元格进行合并,以下分享我的思路;

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;
      }
    },