vue、element 列表 动态合并列

1,133 阅读2分钟

前言

element的提供了列表组件,组件支持行和列的合并,但没办法自动将相同内容合并为一列,需要手动来指定

通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象。

本文据此接口实现动态列的合并

1、template

<el-table
        :data="list"
        border
        stripe
        //合并行或列
        :span-method="mergeCategory"
        :header-cell-style="{background:'#dfe9fc'}"
        style="width: 100%;overflow: auto;">
    <el-table-column
            prop="category"
            label="类别"
            align="center"
            width="210">
    </el-table-column>
    <el-table-column
            prop="itemName"
            label="检测项"
            width="200">
    </el-table-column>
</el-table>

2、script

2.1、先用两个数组存放相同项的个数,这俩个数组在获取列表数据的时候遍历填充
data() {
	return {
	    //...
	    //分类相同项个数,数组
        margeCategoryArr: [], 
        //检测项相同项个数,数组
        margeItemNameArr: [] 
	}
},
2.2、遍历list,计算内容相同的行数,放入数组:
//list为后端返回数据,省略查询步骤

let tempCategory = 1,tempItemName = 1, 

//记录相同行的个数
for(let i = 0; i < list.length-1 ; i ++){

    //处理‘类别’列
	// 前一项和后一项内容相等
	if(list[i].category === list[i+1].category){
	    //边界
		if(i === list.length -2){
			tempCategory = tempCategory +2;
        }else{
			++tempCategory;
        }
	}else{
		this.margeCategoryArr.push(tempCategory);
		//放入数组后重新开始计数
		tempCategory = 1;
	}

    //处理‘检测项’列
	if(list[i].itemName === list[i+1].itemName){
		if(i === list.length -2){
			tempItemName = tempItemName + 2;
        }else{
			++tempItemName;
        }
    }else{
		this.margeItemNameArr.push(tempItemName);
		tempItemName = 1;
    }
}

//将最后一次计数结果放入
this.margeCategoryArr.push(tempCategory);
this.margeItemNameArr.push(tempItemName);
2.3、找到不同项下标与相同行数对应关系

arr为data中的数组; 该对应关系用对象来完成

不同项下标相同行数
0arr[0]
arr[0]arr[1]
arr[0] + arr[1]arr[2]
arr[0] + arr[1] + arr[2]arr[3]
......
getKey(n,arr)arr[n]
getKey实现:
//methods
getKey(n,arr){

	if(n === 0){
		return 0;
    }
	if(n === 1){
		return arr[0]
    }
	return this.getKey(n - 1,arr) + arr[n-1];

}

列表每页10条数据,层级最多10,数量不大用递归实现

mergeCategory实现:
//methods
mergeCategory({ row, column, rowIndex, columnIndex }){

    //开始合并项和合并数对应
	let margeCategoryObj = {}, margeItemNameObj = {};

	this.margeCategoryArr.forEach((item,index,arr) => {
		margeCategoryObj[this.getKey(index,arr)] = arr[index];
    });
	this.margeItemNameArr.forEach((item,index,arr) =>{
		margeItemNameObj[this.getKey(index,arr)] = arr[index];
    });

    //合并分类
    //第一列
	if (columnIndex === 0) {
	    //记录是否需要合并
		let margeCategory = false;
		for(let item in margeCategoryObj){
			//当前行下标和需要合并行下标相等,需要合并
			if(rowIndex == item){

				margeCategory = true;
				
				return {
				    //得到合并数字
					rowspan: margeCategoryObj[item],
					colspan: 1
				};
            }
        }
		if(!margeCategory){
			return {
				rowspan: 0,
				colspan: 1
			};
        }
	}

	//合并检测项
	if (columnIndex === 1) {
		let margeItemName = false;
		console.log(margeItemNameObj);
		for(let item in margeItemNameObj){
			// console.log(rowIndex,item)
			if(rowIndex == item){

				margeItemName = true;
				// console.log('执行return',rowIndex,margeCategoryObj[item]);
				return {
					rowspan: margeItemNameObj[item],
					colspan: 1
				};
			}
		}
		if(!margeItemName){
			return {
				rowspan: 0,
				colspan: 1
			};
		}
	}

}

大功告成