element 动态多级表头

现有数据

[{orgName:'单位一',name:'本科',orgId:'101',number:33},{orgName:'单位一',name:'大专',orgId:'101',number:33},
{orgName:'单位一',name:'中专',orgId:'101',number:30},{orgName:'单位2',name:'本科',orgId:'102',number:33},{orgName:'单位2',name:'大专',orgId:'102',number:33},
{orgName:'单位2',name:'中专',orgId:'102',number:30}]

怎么利用element 实现下面的效果。
image.png
看了官方的多级表头的效果 但是没思路处理成行列都有的数据。可以写死实现 但是 不知道怎么动态处理 name这个参数去实现表头

阅读 2.2k
2 个回答
<script lang="ts" setup>
import _ from "lodash";
import { computed } from "vue";

const data = [
    { orgName: "单位一", name: "本科", orgId: "101", number: 33 },
    { orgName: "单位一", name: "大专", orgId: "101", number: 33 },
    { orgName: "单位一", name: "中专", orgId: "101", number: 30 },
    { orgName: "单位2", name: "本科", orgId: "102", number: 33 },
    { orgName: "单位2", name: "大专", orgId: "102", number: 33 },
    { orgName: "单位2", name: "中专", orgId: "102", number: 30 }
];


function makeRow(list: any[], orgName: string) {
    const total = _.sumBy(list, "number");
    return list.reduce((r, { name, number }) => {
        return Object.assign(r, {
            [name]: number,
            [`${name}%`]: (number / total * 100).toFixed(2)
        });
    }, { orgName, total });
}

const summary = makeRow(
    _(data).groupBy("name")
        .toPairs()
        .map(([name, listt]) => {
            return {
                name,
                number: _.sumBy(listt, "number")
            };
        })
        .value(),
    "全部"
);

function makeRows(data: any[]) {
    return _(data).groupBy("orgName")
        .toPairs()
        .map(([org, list]) => makeRow(list, org))
        .unshift(summary)
        .value();
}

type Column = {
    prop?: string,
    label: string,
    width?: number,
    subs?: Column[]
}

function makeColumns(data: any[]): Column[] {
    const fields = [...new Set(data.map(({ name }) => name))]
        .map(name => ({
            prop: `key_${name}`,
            label: name,
            subs: [
                { prop: name, label: "数量", width: 60 },
                { prop: `${name}%`, label: "占比", width: 60 }
            ]
        }));
    return fields;
}

const rows = computed(() => makeRows(data));
const columns = computed(() => makeColumns(data));

</script>

<template>
    <el-table :data="rows" style="width: 100%">
        <!-- 把这两列做到循环里会显示不出来数据,不明白是什么原因,只能单独拿出来 -->
        <el-table-column prop="orgName" label="组织"></el-table-column>
        <el-table-column prop="total" label="合计"></el-table-column>
        <el-table-column v-for="col in columns" :key="col.prop" :label="col.label" :prop="col.prop" :width="col.width">
            <template v-if="(col.subs?.length ?? 0) > 0">
                <el-table-column v-for="c in col.subs" :key="c.prop" :label="c.label" :prop="c.prop" :width="c.width">
                </el-table-column>
            </template>
        </el-table-column>
    </el-table>
</template>

image.png

正好前段时间做了这个需求 处理动态多级表头image.png
(单元数量和下面户型都是后端返的数量不定)
代码有点多加了很多逻辑,怕你越看越迷,就不粘贴代码了
实现方式就是<el-table-column>里面嵌套<el-table-column>但是表头数据和表单内容是单独的两个数据,表头数据是从表单数据拆分出来的,单独的数据处理表头就比较好操作了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题