element-ui el-table表格组件 动态合并列

效果

codepen 预览地址 合并多个单元格 el-table
在这里插入图片描述

完整 代码

<script src="//unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<div id="app">
<template>
  <div>
    <el-table
      :data="tableData"
      :span-method="objectSpanMethod"
      border
      style="width: 100%; margin-top: 20px">
      <el-table-column
        prop="id"
        label="ID"
        width="180">
      </el-table-column>
  
        <el-table-column
        prop="number"
        label="号码id">
      </el-table-column>
          <el-table-column
        prop="name"
        label="姓名">
      </el-table-column>
      <el-table-column
        prop="amount1"
        label="数值 1(元)">
      </el-table-column>
      <el-table-column
        prop="amount2"
        label="数值 2(元)">
      </el-table-column>
      <el-table-column
        prop="amount3"
        label="数值 3(元)">
      </el-table-column>
    </el-table>
  </div>
</template>
</div>
var Main = {
    
    
    data() {
    
    
      return {
    
    
        storeRowObj:{
    
    },
        storeProNameObj:{
    
    },
        storeHebingObj:{
    
    },
        tableData: [{
    
    
          id: '1',
          name: '王小虎',
          amount1: '0',
          amount2: '4.1',
          amount3: 15,
          number:123456,
        },{
    
    
          id: '1',
          name: '王小虎',
          amount1: '1',
          amount2: '4.1',
          number:123456,
          amount3: 15
        },{
    
    
          id: '1',
          name: '王小虎',
          amount1: '2',
          amount2: '4.1',
          amount3: 15,
          number:456,
        },{
    
    
          id: '2',
          name: '王小虎',
          amount1: '3',
          amount2: '4.1',
          amount3: 15,
          number:567,
          
        },{
    
    
          id: '2',
          name: '王小虎',
          amount1: '4',
          amount2: '4.1',
          number:567,
          amount3: 15
          
        },{
    
    
          id: '2',
          name: '王小虎',
          amount1: '5',
          amount2: '4.1',
          amount3: 15,
          number:789,
        },{
    
    
          id: '2',
          name: '王小虎',
          amount1: '6',
          amount2: '4.1',
          number:789,
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '7',
          amount2: '4.1',
          number:789,
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '8',
          number:645654465,
          amount2: '4.1',
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '9',
          amount2: '4.1',
          number:567,
          amount3: 15
          
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '10',
          amount2: '4.1',
          amount3: 15,
          number:789,
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '11',
          amount2: '4.1',
          number:789,
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '12',
          amount2: '4.1',
          number:789,
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '13',
          number:645654465,
          amount2: '4.1',
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '13',
          number:'',
          amount2: '4.1',
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '13',
          number:'645654465',
          amount2: '6',
          amount3: 15
        },{
    
    
          id: '3',
          name: '王小虎',
          amount1: '13',
          number:645654465,
          amount2: '4.1',
          amount3: 15
        },
        {
    
    
          id: '3',
          name: '王小虎',
          amount1: '13',
          number:645654465,
          amount2: '4.1',
          amount3: 15
        },
        {
    
    
          id: '3',
          name: '王小虎',
          amount1: '13',
          number:645654468,
          amount2: '4.1',
          amount3: 15
        },]
      };
    },
  created(){
    
    
    let options = {
    
    
      //合并顺序必须 优先级从高往低排列
			hebingProps: [
				{
    
    
					proName: 'id',
					columnIndexList: [0]
				},
				{
    
    
					proName: 'number',
					columnIndexList: [1,2]
				},
				{
    
    
					proName: 'amount2',
					columnIndexList: [4]
				},
				{
    
    
					proName: 'amount3',
					columnIndexList: [5]
				}
			]
		};
    this.tableData =  this.disposalData(this.tableData,options)
  }, 
    methods: {
    
    
      //  判断是否为空
      isEmpty(value){
    
    
        if(String(value)=='0'){
    
    
          return true;
        }

        if(!value){
    
    
          return false
        }
        return true;
      },
            // 判断上一个 proName 的值 是否相等 
              previousOneProNameValueAllEquality(hebingProps,currentProName,currentItem,storeItem){
    
     
      
        if(!storeItem){
    
    
          return true;
        }
      let previousProName = null;
        for(let i=0;i<hebingProps.length;i++){
    
    
          let item = hebingProps[i];
          if(item.proName==currentProName){
    
    
            break;
          }
          previousProName = item.proName;
        }
      // console.log(previousProName,currentProName);
      
      if(previousProName){
    
    
          let otherProNameList = [previousProName];
          let isEquality = true;
          for(let i=0;i<otherProNameList.length;i++){
    
    
            let key = otherProNameList[i];
            if(currentItem[key]!=storeItem[key]){
    
    
              isEquality = false;
              break;
            }
          }
          return isEquality;
        }
      return true;
      },
      // 判断之前的proName 是否全部相等 
    previousProNameValueAllEquality(hebingProps,currentProName,currentItem,storeItem){
    
    
        if(!storeItem){
    
    
          return true;
        }
        let otherProNameList =[];
        let proNameIndex = -1;
        otherProNameList= hebingProps.filter((item,index)=>{
    
    
          if(item.proName==currentProName){
    
    
            proNameIndex = index;
          }
          if(proNameIndex==-1){
    
    
            return true;
          } 
          else if(proNameIndex==0 || index >= proNameIndex){
    
    
           return false;
          }
          return true;
          
        }).map(item=>item.proName);
        if(!otherProNameList.length){
    
    
          return true;
        }
        let isEquality = true;
        for(let i=0;i<otherProNameList.length;i++){
    
    
          let key = otherProNameList[i];
          if(currentItem[key]!=storeItem[key]){
    
    
            isEquality = false;
            break;
          }
        }
        return isEquality;
      },
      //整理需要合并的表格数据
     	/**
			options ={
			//需要合并的参数
		    	hebingProps: [
					{
						proName: 'id', //需要合并的prop 名称
						columnIndexList: [0] // //需要合并的 columnIndex下标列表
					},
				]
			}	
		*/ 
      disposalData(list, options = {
     
     }) {
    
    
      options.hebingProps.forEach((oItem) => {
    
    
				let {
    
    
					proName,
					columnIndexList
				} = oItem;
				let storeValue, storeIndex,storePreItem,hebing;
				list.forEach((item, index) => {
    
    
          // let isEquality = this.previousOneProNameValueAllEquality(options.hebingProps,proName,item,storePreItem);
          let isEquality = this.previousProNameValueAllEquality(options.hebingProps,proName,item,storePreItem);  
					if (storeValue != item[proName] || !isEquality) {
    
    
						if (index != 0) {
    
    
							let currentItem = list[storeIndex];
							if(hebing>1){
    
    
                let objs = {
    
    
								[proName]: {
    
    
									hebing,
                  proName,
									columnIndexList
								}
							}
                if (!currentItem.tableOptions) {
    
    
								currentItem.tableOptions = {
    
    
									...objs
								}
							} else {
    
    
								currentItem.tableOptions = {
    
    
									...currentItem.tableOptions,
									...objs
								}
							}
              }
						}
						storeValue = item[proName];
						storeIndex = index;
						hebing = 1;
					} else if (storeValue == item[proName]  && this.isEmpty(item[proName])  && index != 0 && isEquality ) {
    
    
						hebing += 1;
							if(index*1+1==list.length){
    
    
                let currentItem = list[storeIndex];
                if(hebing>1){
    
    
                  let objs = {
    
    
                    [proName]: {
    
    
                      hebing,
                  proName,
                      columnIndexList
                    }
                  }
                  if (!currentItem.tableOptions) {
    
    
                    currentItem.tableOptions = {
    
    
                      ...objs
                    }
                  } else {
    
    
                    currentItem.tableOptions = {
    
    
                      ...currentItem.tableOptions,
                      ...objs
                    }
                  }
                }
							}
					}
          storePreItem = item;
				})
			})
			return list
		},
     objectSpanMethod({
     
     
			row,
			column,
			rowIndex,
			columnIndex
		}) {
    
    
			let {
    
    
				tableOptions
			} = row;
			if (tableOptions) {
    
    
				for (let key in tableOptions) {
    
    
					let item = tableOptions[key];  
					let {
    
    
						hebing = 0, columnIndexList = [], proName = ''
					} = item;
					if (columnIndexList.length && columnIndexList.includes(columnIndex)) {
    
    
						// let hebing = row.hebing || null
						if (hebing) {
    
    
              let  storeProName  = proName;
							this.storeProNameObj[proName] = true;
							this.storeRowObj[storeProName + columnIndex] = rowIndex;
							this.storeHebingObj[storeProName + columnIndex] = hebing
							return {
    
    
								rowspan: hebing,
								colspan: 1,
							}
						} 
					}
				}
			}
       for(let key in this.storeProNameObj){
    
    
          let storeProName = key
          let storeRowIndex = this.storeRowObj[storeProName + columnIndex]
          let hebing = this.storeHebingObj[storeProName + columnIndex];
          if (storeProName && storeRowIndex  != undefined &&
           storeRowIndex + hebing  > rowIndex) {
    
    
			return {
    
    
					rowspan: 0,
					colspan: 0,
				}
			}
        }
     }
    }
  };

var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')


原理

在这里插入图片描述
主要是原始的tableData表格数据
经过处理后,
在tableData 数据 需要合并的项插入 tableOptions 属性
tableOptions 属性中包含了需要合并的表格列项列表columnIndexList 及判断 prop名称 proName
然后 使用 合并行或列的计算方法:span-method="objectSpanMethod"
objectSpanMethod 通过判断 tableOptions 实现合并列

猜你喜欢

转载自blog.csdn.net/weixin_43245095/article/details/128629522