vue3.0 el-table 动态合并单元格

发布时间 2023-09-05 16:42:51作者: flyComeOn
<el-table 
        v-resize:34 style="margin: 10px 0 10px" :data="tableData"     
        :header-cell-style="{background: '#F6F6F6', height: '10px','text-align':'center'}"
        :span-method="objectSpanMethod">
        <el-table-column type="index" label="NO." width="55" />
          <el-table-column prop="branchName" label="网点名称" align="center" />
          <el-table-column prop="boxName" label="款箱名称" align="center" />
          <el-table-column prop="isEmpty" label="是否空箱" align="center" />
          <el-table-column prop="inventoryStatus" label="盘点状态" align="center"/>
          <el-table-column label="操作" align="center" fixed="right" width='100px'>
            <template #default="scope">
              <el-button-group>
                <el-button link type="danger" title="删除" :icon="Delete" @click="handleDelete(scope.row.id)"/>
              </el-button-group>
            </template>
          </el-table-column>
      </el-table>

2、方法

// 给列表赋值
const tableData = [
  {
    branchName: '舜泰支行',
    boxName: '舜泰支行一号箱',
    isEmpty: '是',
    inventoryStatus:'有交接未盘点'
  },
  {
    branchName: '舜泰支行',
    boxName: '舜泰支行二号箱',
    isEmpty: '是',
    inventoryStatus:'有交接未盘点'
  },
  {
    branchName: '舜泰支行',
    boxName: '舜泰支行三号箱',
    isEmpty: '否',
    inventoryStatus:'有交接未盘点'
  },
  {
    branchName: '汉峪金谷支行',
    boxName: '汉峪金谷一号箱',
    isEmpty: '否',
    inventoryStatus:'无交接'
  },
   {
    branchName: '汉峪金谷支行',
    boxName:'汉峪金谷二号箱',
    isEmpty: '是',
    inventoryStatus:'有交接未盘点'
  },
  {
    branchName: '汉峪金谷支行',
    boxName: '汉峪金谷三号箱',
    isEmpty: '是',
    inventoryStatus:'有交接未盘点'
  },
  {
    branchName: '汉峪金谷支行',
    boxName: '汉峪金谷四号箱',
    isEmpty: '否',
    inventoryStatus:'有交接已盘点'
  },
]
// 正常应该是获得后台数据之后调用setTableRowSpan()方法
onMounted(()=>{
  // 需要合并的字段名,按照合并登记来排序
  const colFields=['branchName']
  // 表格数据,表格字段
  setTableRowSpan(tableData,colFields)
})

// 设置合并的行和列
const setTableRowSpan = (tableData:any,colFields:any) =>{
  let lastItem:any = []
  // 循环需要合并的列
  colFields.forEach((field:any, index:any) =>{
    tableData.forEach((item:any) =>{
      // 存值,把合并字段存入行,为了合并单元格时检索列是否含有该字段
      item.mergeCell = colFields
      // 合并的字段出现的次数
      const rowSpan = `rowspan_${field}`
      // 比较上一次的存值和该轮的合并字段,判断是否合并到上个单元格
      if( colFields.slice(0,index + 1).every(e =>lastItem[e] === item[e] )){
          // 如果是,合并行;
          item[rowSpan] = 0 // 该轮合并字段数量存0
          // 上轮合并字段数量+1
          lastItem[rowSpan] +=1
      }else{
          //初始化进入&& 如果不是,完成一次同类合并,lastItem重新赋值,进入下一次计算
          item[rowSpan] = 1 // 该轮合并字段第一次出现,数量存1
          // 改变比较对象,重新赋值,进行下一次计算
          lastItem = item
      }
    })
  })
}
// 列表合并单元格发方法
const objectSpanMethod = ({row, column, rowIndex, columnIndex}) => {
  if(row.mergeCell.includes(column.property)){
    const rowspan = row[`rowspan_${column.property}`]
    if(rowspan){
      return { rowspan:rowspan, colspan:1}
    }else {
       return { rowspan:0, colspan:0}
    }
  }
}

3、效果图