element-ui el-table form component dynamically merges columns

Effect

codepen preview address merge multiple cells el-table
insert image description here

full code

<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')


principle

insert image description here
Mainly the original tableData table data
After processing,
the items that need to be merged in the tableData data are inserted into the tableOptions attribute. The
tableOptions attribute contains the table column item list columnIndexList that needs to be merged and the judgment prop name proName.
Then use the calculation method of merging rows or columns :span-method="objectSpanMethod"
objectSpanMethod to pass Judging tableOptions to achieve merged columns

Guess you like

Origin blog.csdn.net/weixin_43245095/article/details/128629522