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>
相关推荐
GISer_Jing1 小时前
WebGL跨端兼容实战:移动端适配全攻略
前端·aigc·webgl
daols881 小时前
vue 甘特图 vxe-gantt 自定义任务条插槽模板的用法
vue.js·vxe-gantt
迦南giser1 小时前
前端性能——传输优化
前端
小白_ysf1 小时前
Vue 中常见的加密方法(对称、非对称、杂凑算法)
前端·vue.js·算法
2501_944448002 小时前
Flutter for OpenHarmony衣橱管家App实战:支持我们功能实现
android·javascript·flutter
人工智能训练7 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪8 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi9229 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233229 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头882111 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos