合并el-table多行多列表格

本文介绍了如何在Vue.js中处理动态数据时实现复杂表格的行/列合并。通过`<el-table>`组件,结合`span-method`属性,利用`rowspan`和`colspan`实现动态合并。关键在于比较相邻数据项的特定字段,判断是否需要合并,并调整`rowspan`和`colspan`的值。文章提供了详细的代码示例和解释,适用于需要处理多行多列合并的前端开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开发中经常会遇到复杂型表格,多行多列的操作并不可避免,如果是静态数据可以colspan rowspan 跨行写死即可,代表占列、行数,如果是动态数据需要处理对数据做相应的处理。

如图:

 合并标段名称,角色名称.....如有更多行亦是如此,直接上代码

<el-table
   ref="smallTable"
   :data="state.tableData"
   :span-method="objectSpanMethod"
   class="tableLimit"
   max-height="500"
 >
   <el-table-column align="center" label="标段名称" prop="tenderName" />
   <el-table-column align="center" label="角色名称" prop="roleType">
      <template #default="{row}">{{ roleTypeList[row.roleType] }}</template>
   </el-table-column>
   <el-table-column align="center" label="人员名称" prop="userName" />
   <el-table-column align="center" label="未签署人员" prop="isSign">
      <template #default="{row}">
        <i v-if="row.isSign==='00'" class="el-icon-star-off" />
      </template>
   </el-table-column>
   <el-table-column align="center" label="已签署人员" prop="attendStatus">
      <template #default="{row}">
        <i v-if="row.isSign==='01'" class="el-icon-star-off" />
      </template>
   </el-table-column>
</el-table>

<script setup>
...引入api
// 数据
const state =  reactive({
   ...
   tableData:[],
   fieldArr:['tenderName','roleType'], // 需要合并的字段名,按照合并等级来排序
   ...
})
// 方法
...
const getData = async () =>{
   ...
   const list = await api(params).then(res => {
       return res.data.records
   })
   ...
   // 数据处理 如果后端返的数据已经排过序了,(这边的排序是指不会出现标段名,roleType混乱情况)
   state.tableData = list
   // 如果没排序,前端这边处理下 ....
   // list.sort((a,b) => {
   //  if(a.tenderSort === b.tenderSort){
   //      return Number(a.roleType.slice(-1)) - Number(b.roleType.slice(-1))
   //  }
   //  return a.tenderSort - b.tenderSort
   // })
   this.getSpanArr(state.tableData,state.fieldArr)
}
getSpanArr(data, fieldArr) {
      let lastItem = {}  // 上一次data的i
      fieldArr.forEach((field, ind) => {
        data.forEach(i => {
          i.mergeCell = fieldArr //存值,把合并字段存入行为了合并单元格时检索列是否含有该字段
          const rowSpan = `rowspan_${field}` // 合并的字段出现的次数
          // 比较上一次的存值i和该轮i的合并字段,判断是否合并到上个单元格
          if (fieldArr.slice(0, ind + 1).every(e => lastItem[e] === i[e])) {
            // 如果是,合并行
            i[rowSpan] = 0  // 该轮合并字段数量存0
            lastItem[rowSpan] += 1 // 上轮合并字段数量+1
          } else {
            // 初始化进入 && 如果不是,完成一次同类合并,lastItem重新赋值,进入下一次计算
            i[rowSpan] = 1 // 该轮合并字段第一次出现 数量存1
            lastItem = i // 并且改变比较对象,重新赋值,进行下一次计算
          }
        })
      })
    },

// 合并列
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 判断当前单元格是否需要合并
      // 之前将每个row存入合并字段数组mergeCell,同时column列对象有property属性,即为el-table-column的prop属性
      if (row.mergeCell.includes(column.property)) {
        const rowspan = row[`rowspan_${column.property}`]
        if (rowspan) { // 如果有则把row的字段合并数量存入rowspan colspan存1
          return { rowspan, colspan: 1 }
        } else { // 如果没有,则置0
          return { rowspan: 0, colspan: 0 }
        }
      }
    },
</script>

代码注释写的很清楚,应该看一下就明白了,这边只写了多行多列合并,如果需要同时合并多行多列方法一样,主旨就是比较待合并字段,比较这次和上次是否一样,不是则,新索引的数量存1,如果是则老索引的数量+1,新索引的数量存0,不管是之前单列合并行的标志位pos 还是这种存i方式,都可以,记录一下。

### Element UI `el-table` 表头合并行或列实现方法 #### 使用 `span-method` 方法自定义合并逻辑 为了在 `el-table` 中实现表头的行列合并,可以利用 `header-cell-style` 和 `span-method` 属性。具体来说: 对于表头单元格,可以通过设置 `span-method` 来控制哪些单元格应该被合并以及它们应该如何跨越多行多列。 下面是一个具体的例子展示如何使用这些特性来创建具有合并表头的表格[^1]: ```html <template> <div> <!-- 定义 table --> <el-table :data="tableData" border style="width: 100%" :span-method="objectSpanMethod"> <el-table-column prop="date" label="日期"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> </div> </template> <script> export default { data() { return { tableData: [ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles' }, { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles' } ] }; }, methods: { objectSpanMethod({ row, column, rowIndex, columnIndex }) { if (columnIndex === 0) { if (rowIndex % 2 === 0) { return [1, 2]; // 合并当前行向下两行 } else { return [0, 0]; } } if (columnIndex === 1 && rowIndex % 2 !== 0) { return [0, 0]; } if(columnIndex===2){ if(rowIndex%2===0){ return [2,1];//向下行合并两个单元格 } } } } }; </script> ``` 此代码片段展示了怎样通过编程方式指定哪几行或列应当被合并在一起。在这个案例里,日期列每隔一行就会与其他相邻的一行合并成一个更大的单元格;而名字列则仅当其位于偶数索引位置时才会参与合并操作。至于地址栏,则是在奇数行的情况下跨过下一行进行显示。 另外,在某些情况下可能还需要调整 CSS 样式以确保视觉上的完美呈现,特别是涉及到不同高度的内容项时。这通常涉及修改 `.el-table__cell` 类的选择器样式[^3]。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值