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>
相关推荐
华玥作者6 小时前
[特殊字符] VitePress 对接 Algolia AI 问答(DocSearch + AI Search)完整实战(下)
前端·人工智能·ai
Mr Xu_6 小时前
告别冗长 switch-case:Vue 项目中基于映射表的优雅路由数据匹配方案
前端·javascript·vue.js
前端摸鱼匠6 小时前
Vue 3 的toRefs保持响应性:讲解toRefs在解构响应式对象时的作用
前端·javascript·vue.js·前端框架·ecmascript
lang201509287 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
好家伙VCC7 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
未来之窗软件服务8 小时前
未来之窗昭和仙君(六十五)Vue与跨地区多部门开发—东方仙盟练气
前端·javascript·vue.js·仙盟创梦ide·东方仙盟·昭和仙君
嘿起屁儿整8 小时前
面试点(网络层面)
前端·网络
VT.馒头8 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
phltxy9 小时前
Vue 核心特性实战指南:指令、样式绑定、计算属性与侦听器
前端·javascript·vue.js
Byron070710 小时前
Vue 中使用 Tiptap 富文本编辑器的完整指南
前端·javascript·vue.js