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 实现合并列

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值