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>
相关推荐
爱上大树的小猪1 分钟前
【前端进阶】深入解析 Flexbox 布局中的 flex-shrink 与 gap 兼容性问题
前端·css·面试
南囝coding1 分钟前
做Docx预览,一定要做这个神库!!
前端·vue.js·面试
打野赵怀真2 分钟前
怎样提高微信小程序的渲染性能?
前端·javascript
邵洛4 分钟前
一、【UnoCss / unibest】样式篇
前端
Mike_jia4 分钟前
Wireshark 网络数据包分析全解:从抓包入门到企业级实战
前端
三原7 分钟前
前端微应用-乾坤(qiankun)原理分析-import-html-entry
前端·架构·前端框架
Mintopia8 分钟前
Three.js 学习第一天:基础搭建与核心概念
前端·javascript·three.js
打野赵怀真8 分钟前
怎样提高微信小程序的加载速度?
前端·javascript
前端拧螺丝9 分钟前
定制化 Docsify 文档框架实战分享
前端
凯哥19709 分钟前
Sciter.js 新手指南-GUI开发中使用系统托盘图标 (trayIcon)
前端