有一个表格的需求是:当选择的年份时表头展示的数据是1月-12月,当选择的是月份时展示的是1-31日,当点击月份或日期的时候要展示二级子表头
实现需求的难点就在于如何拼凑数据,因为我使用的element-plus,下面就说说是如何实现需求的吧
首先是拼凑表头数据(系统名称,1月-12月),即cols
<el-table
ref="table"
style="margin-top: 50px; height: 69vh"
:data="tableData"
:key="isUpdate"
@row-click="handleRow"
@header-click="handleHeader"
>
<el-table-column
label="系统名称"
prop="rowLabel"
width="150"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
v-for="(col, index) in cols"
:key="col"
:prop="col.prop"
:label="col.label"
show-overflow-tooltip
align="center"
>
<template v-if="col.subColumn">
<el-table-column
v-for="(sub, i) in col.subColumn"
:key="sub"
:label="sub"
:width="sub.width"
show-overflow-tooltip
align="center"
>
<template #default="scope">
<span>{{ scope.row["children" + index][i] }}</span>
</template>
</el-table-column>
</template>
</el-table-column>
</el-table>
1.将cols拼凑成类似这样的数据:
[
{label: ‘01月’, prop: ‘list0’},
{label: ‘02月’, prop: ‘list1’},
{label: ‘03月’, prop: ‘list2’},
{label: ‘04月’, prop: ‘list3’},
{label: ‘年度’, prop: ‘total’},
]
2.接下来就要去处理tableData的数据了,需要将tableData处理成这样的格式:
[
{rowLabel:“智能工作台”, list0: 12, list1: 22, list3: 13, total: 37},
{rowLabel:“OP系统”, list0: 12, list1: 22, list3: 13, total: 37},
{rowLabel:“投资管家”, list0: 12, list1: 22, list3: 13, total: 37},
{rowLabel:“360系统”, list0: 12, list1: 22, list3: 13, total: 37},
]
第二步,实现点击表头月份展开详情
const handleHeader = (column: any) => {
// 点击的非月份直接return
if (isNaN(parseInt(column.label))) return;
const index = cols.value.findIndex((item) => item.prop === "detail");
if (index === -1) {
// 如果没有详情,点击不展开
if (!childrenLabels.value.length) return;
cols.value.splice(parseInt(column.label), 0, {
label: "生产缺陷状态",
prop: "detail",
width: "180",
showOverflowTooltip: true,
subColumn: childrenLabels, // 二级表头的数组, ["处理中", "新建", "已拒绝", "已修复", "关闭"]
});
} else {
if (parseInt(column.label) !== index) {
// 点击其他月份
cols.value.splice(
parseInt(column.label),
0,
cols.value.splice(index, 1)[0]
);
} else {
cols.value.splice(index, 1);
}
}
isUpdate.value = !isUpdate.value;
};
最后是处理行数据,赋值给tableData,要得到的数据类型是这样的:
[
{rowLabel:“智能工作台”, list0: 12, list1: 22, list3: 13, total: 37, children0:[1,2,3,4], children1:[0,0,0,0], children2:[1,2,2,2], children3: [3,3,3,3]},
{rowLabel:“OP系统”, list0: 12, list1: 22, list3: 13, total: 37, children0:[1,2,3,4], children1:[0,0,0,0], children2:[1,2,2,2], children3: [3,3,3,3]},
{rowLabel:“投资管家”, list0: 12, list1: 22, list3: 13, total: 37, children0:[1,2,3,4], children1:[0,0,0,0], children2:[1,2,2,2], children3: [3,3,3,3]},
{rowLabel:“360系统”, list0: 12, list1: 22, list3: 13, total: 37, children0:[1,2,3,4], children1:[0,0,0,0], children2:[1,2,2,2], children3: [3,3,3,3]},
]
// 处理行数据
const getRowData = (datasets: any[]) => {
const dealDatasets = Object.keys(datasets).map((key) => {
const data = datasets[key];
const row: Record<string | number | symbol, any> = { rowLabel: key };
let total = 0;
data.forEach((item, index) => {
row["list" + index] = item.total;
row["children" + index] = item.children;
total += item.total;
});
row.total = total;
return row;
});
// 计算‘总计’行数据
let result = {};
dealDatasets.forEach((data) => {
Object.keys(data).forEach((key) => {
if (!result[key]) {
if (key === "rowLabel") {
result[key] = "总计";
} else if (key.startsWith("children")) {
result[key] = new Array(data[key].length).fill(0);
} else {
result[key] = 0;
}
}
});
});
dealDatasets.forEach((data) => {
Object.keys(data).forEach((key) => {
if (key !== "rowLabel" && !key.startsWith("children")) {
result[key] += data[key];
} else if (key.startsWith("children")) {
result[key] = result[key].map((val, index) => val + data[key][index]);
}
});
});
return [...dealDatasets, result];
};