Vue+Element-UI el-table表格根据指定条件动态合并行span-method

当涉及到展示复杂数据的表格时,Element UI 中的 el-table 是一个非常有用的组件。在某些情况下,可能需要对表格进行合并显示以提高可读性。

案例需求:页面中有个表格组件,其中包含了一些学生的姓名、年级、负责班级和科目成绩等信息。我们希望能够合并显示相同学生的信息,并且在第一列(姓名)和第二列(负责年级)中进行合并操作。

1.处理后端返回的数据为表格所需要的数据

后端根据业务返回的数据:

此时我们需要将classList里的数据拉平放入新数组里,并且需要给每一份数据第一个要合并的数据做个标识,标明要合并几行

javascript 复制代码
 this.tableData = []
      res.data.forEach(item => {
        if (item.classList) {
          item.classList.forEach((item2, index) => {
            this.tableData.push({
              rowspan: index === 0 ? item.classList.length : null, // 需要合并的行数 只在合并首行也就是index==0时定义标识
              colspan: 1,
              ...item,
              ...item2
            })
          })
        }
      })

2.利用el-table的属性spanMethod去定义合并方法

  1. el-table标签上定义span-method方法
html 复制代码
  <el-table
    :data="tableData"
    :span-method="spanMethod">
  1. methods里增加spanMethod方法
javascript 复制代码
    spanMethod({ row, column, rowIndex, columnIndex }) {
      if ([0, 1].includes(columnIndex)) {
        if (row.rowspan && row.rowspan > 0) {
          return {
            rowspan: row.rowspan, // 需要合并的行数
            colspan: 1
          }
        } else {
          // 不合并
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
    }

3.完整代码:

javascript 复制代码
<template>
  <el-table
    :data="tableData"
    :span-method="spanMethod"
    style="width: 100%">
    <el-table-column
      prop="name"
      label="姓名"
      width="180">
    </el-table-column>
    <el-table-column
      prop="grade"
      label="负责年级">
    </el-table-column>
    <el-table-column
      prop="class"
      label="负责班级">
    </el-table-column>
    <el-table-column
      prop="sub1"
      label="科目1">
    </el-table-column>
    <el-table-column
      prop="score1"
      label="班级总分1">
    </el-table-column>
    <el-table-column
      prop="sub2"
      label="科目2">
    </el-table-column>
    <el-table-column
      prop="score2"
      label="班级总分2">
    </el-table-column>
    <el-table-column
      prop="sub3"
      label="科目3">
    </el-table-column>
    <el-table-column
      prop="score3"
      label="班级总分3">
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: []
    }
  },
  created() {
    this.getData()
  },
  methods: {
    getData() {
      // 这里模拟后端返回的数据 
      let res = {
        data: [
          {
            id: 1,
            name: '张三',
            grade: '一年级',
            classList: [
              {
                class: '1班',
                sub1: '语文',
                score1: '90',
                sub2: '数学',
                score2: '90',
                sub3: '英语',
                score3: '90'
              },
              {
                class: '2班',
                sub1: '物理',
                score1: '90',
                sub2: '化学',
                score2: '90',
                sub3: '英语',
                score3: '90'
              }
            ]
          }, {
            id: 2,
            name: '李四',
            grade: '二年级',
            classList: [
              {
                class: '1班',
                sub1: '语文',
                score1: '90',
                sub2: '数学',
                score2: '90',
                sub3: '英语',
                score3: '90'
              },
              {
                class: '2班',
                sub1: '-',
                score1: '-',
                sub2: '化学',
                score2: '90',
                sub3: '英语',
                score3: '90'
              }
            ]
          },
          {
            id: 3,
            name: '李四',
            grade: '二年级',
            classList: [
              {
                class: '1班',
                sub1: '语文',
                score1: '90',
                sub2: '数学',
                score2: '90',
                sub3: '英语',
                score3: '90'
              }
            ]
          }
        ]
      }
      this.tableData = []
      res.data.forEach(item => {
        if (item.classList) {
          item.classList.forEach((item2, index) => {
            this.tableData.push({
              rowspan: index === 0 ? item.classList.length : null, // 需要合并的行数 只在合并首行也就是index==0时定义标识
              colspan: 1,
              ...item,
              ...item2
            })
          })
        }
      })
    },
    spanMethod({ row, column, rowIndex, columnIndex }) {
      if ([0, 1].includes(columnIndex)) {
        if (row.rowspan && row.rowspan > 0) {
          return {
            rowspan: row.rowspan, // 需要合并的行数
            colspan: 1
          }
        } else {
          // 不合并
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
相关推荐
excel13 小时前
Node.js 断言与测试框架示例对比
前端
天蓝色的鱼鱼15 小时前
前端开发者的组件设计之痛:为什么我的组件总是难以维护?
前端·react.js
codingandsleeping15 小时前
使用orval自动拉取swagger文档并生成ts接口
前端·javascript
石金龙16 小时前
[译] Composition in CSS
前端·css
白水清风16 小时前
微前端学习记录(qiankun、wujie、micro-app)
前端·javascript·前端工程化
Ticnix16 小时前
函数封装实现Echarts多表渲染/叠加渲染
前端·echarts
用户221520442780016 小时前
new、原型和原型链浅析
前端·javascript
阿星做前端16 小时前
coze源码解读: space develop 页面
前端·javascript
叫我小窝吧16 小时前
Promise 的使用
前端·javascript
NBtab16 小时前
Vite + Vue3项目版本更新检查与页面自动刷新方案
前端