element el-table渲染二维对象数组

效果图如下

完整代码如下

html 复制代码
<template>
  <section>
    <h1>el-table渲染二维对象数组</h1>
    <el-table :data="_data.tableList" :span-method="spanMethod" border>
      <el-table-column prop="id" label="ID" />
      <el-table-column prop="name" label="姓名" />
      <el-table-column label="工作情况" align="center">
        <el-table-column prop="children_key" label="工号" />
        <el-table-column prop="children_work" label="上班天数" width="100"/>
        <el-table-column prop="children_money" label="实发工资" width="100"/>
      </el-table-column>
    </el-table>
  </section>
</template>

<script setup>
import { reactive, onMounted } from 'vue'

const _data = reactive({
  // 表格数据
  tableList: [],
  // 表格合并数据
  spanArr: []
})

onMounted(() => {
  getList()
})

// 获取表格原数据
const getList = () => {
  var ApiList = [
    {
      id: 1, name: '爱坤',
      children: []
    },
    {
      id: 2, name: '刘德华',
      children: [
        { key: 1, work: 43, money: 500 },
      ]
    },
    {
      id: 3, name: '周润发',
      children: [
        { key: 2, work: 12, money: 589 },
        { key: 3, work: 9, money: 70 },
      ]
    },
  ]
  //【2】不要赋值到data,而是对数据进行"处理"
  // 由于表格无法渲染二级数据,所以对二维数组进行"平级"处理
  // 让数据都处于一级,这样每行就可以顺利展示了
  var temp = []//临时变量
  ApiList.forEach((item) => {//遍历第1层
    var obj = {}//临时变量
    if(item.children.length == 0) {//如果没有下级(空数组)
      obj['children_key'] = ''//工号
      obj['children_work'] = ''//上班天数
      obj['children_money'] = ''//实发工资
      temp.push({ ...obj, ...item })//合并两个对象
    }
    // 有下级,存在
    item.children.forEach((row) => {//遍历第2层
      obj['children_key'] = row.key//工号
      obj['children_work'] = row.work//上班天数
      obj['children_money'] = row.money//实发工资
      temp.push({ ...obj, ...item })//合并两个对象
    })
  })
  // 【3】数据处理完,需要对单元格合并做一些处理
  // 虽然你的数据可以平级展示,但会存在"相同"的一些数据
  getSpanArr(temp)
  //【4】全部完事,赋值data进行渲染即可
  // 如果你有加载效果,在这里赋值完毕后解开即可
  _data.tableList = temp
}

// 表格组件的合并方法
const spanMethod = ({ rowIndex, columnIndex }) => {
  // 要合并哪些列,自己看参数,具体详见文档
  if (columnIndex === 0 || columnIndex === 1) {
        const _row = _data.spanArr[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
            rowspan: _row, //合并的行数
            colspan: _col //合并的列数,设为0则直接不显示
        }
    }
}

// 计算表格单元格合并数据(判断当前元素与上一个元素是否相同)
// 如果当前数据和上一个相同,意味着它是一组的数据,进行合并
// 计算完毕后,赋值给"_data.spanArr",请根据你的情况修改
const getSpanArr = (list) => {
	// 每次计算前,必须重置清空
    _data.spanArr = []
    // 正式开始
    let pos = 0
    for (let i = 0; i < list.length; i++) {
        if (i === 0) {
            _data.spanArr.push(1);
            pos = 0
        } else {
            // 判断当前元素与上一个元素是否相同,你自己的项目要根据自己的情况进行修改!
            // 你自己的项目要根据自己的情况进行修改!你自己的项目要根据自己的情况进行修改!
            // 除了改这里,其他地方不用动,除非你读得懂代码
            // 重点!!请注意!!!这里的 [name]是关键,意味着使用name进行判断!
            // 重点!!请注意!!!这里的 [name]是关键,意味着使用name进行判断!
            // 重点!!请注意!!!这里的 [name]是关键,意味着使用name进行判断!
            if (list[i].name === list[i - 1].name) {
                _data.spanArr[pos] += 1;
                _data.spanArr.push(0);
            } else {
                _data.spanArr.push(1);
                pos = i;
            }
        }
    }
}

</script>
相关推荐
风继续吹..2 小时前
后台管理系统权限管理:前端实现详解
前端·vue
yuanmenglxb20043 小时前
前端工程化包管理器:从npm基础到nvm多版本管理实战
前端·前端工程化
新手小新3 小时前
C++游戏开发(2)
开发语言·前端·c++
我不吃饼干4 小时前
【TypeScript】三分钟让 Trae、Cursor 用上你自己的 MCP
前端·typescript·trae
飞翔的佩奇4 小时前
基于SpringBoot+MyBatis+MySQL+VUE实现的经方药食两用服务平台管理系统(附源码+数据库+毕业论文+部署教程+配套软件)
数据库·vue.js·spring boot·mysql·毕业设计·mybatis·经方药食两用平台
小杨同学yx5 小时前
前端三剑客之Css---day3
前端·css
星月心城6 小时前
Promise之什么是promise?(01)
javascript
二川bro6 小时前
第二篇:Three.js核心三要素:场景、相机、渲染器
开发语言·javascript·数码相机
Mintopia6 小时前
🧱 用三维点亮前端宇宙:构建你自己的 Three.js 组件库
前端·javascript·three.js
故事与九7 小时前
vue3使用vue-pdf-embed实现前端PDF在线预览
前端·vue.js·pdf