1. 为什么我们需要动态多级表头?
做后台管理系统,尤其是数据报表、生产看板这类功能,最头疼的就是表头。产品经理今天说:“咱们这个生产数据,要按车间、按班组、按设备类型来展示。”明天又说:“客户想自己选要看哪几个维度,表头要能变。”如果每次都手动去写死<vxe-column>,那代码量会爆炸,维护起来更是噩梦。
我接手过一个项目,最初就是静态表头。后来业务扩展,增加了十几个分析维度,每次改需求,前端和后端都要对齐字段,然后我这边吭哧吭哧改模板,测试一遍遍验证对齐。有一次半夜上线,就因为一个表头字段名对不上,导致整张表数据错位,差点出大事故。从那以后,我就铁了心要把表头做成动态的、可配置的。
动态构建多级表头,核心思想就一句话:让表头的结构由数据驱动,而不是写死在模板里。Vxe-table 本身对动态列的支持就很好,再结合 Vue 的响应式和 v-for 指令,我们能轻松实现这个目标。这意味着,后端只需要返回一份描述了表头层级和结构的配置数据,前端就能自动渲染出对应的复杂表头,前后端彻底解耦。业务再怎么变,我前端模板可能一行都不用改,后端调整配置数据就行了。
这不仅仅是偷懒,更是为了应对业务的快速变化。想象一下,你的系统要支持用户自定义报表,用户在前端拖拽几个维度,生成一个新的表头结构,如果没有动态构建能力,这功能根本没法做。所以,掌握这套方案,是你从“写页面”迈向“做系统”的关键一步。
2. 核心思路拆解:如何用数据描述表头?
在动手写代码之前,我们得先想清楚,一份什么样的数据,才能完整描述出一个多级表头?Vxe-table 的列配置非常灵活,我们要利用起来。
2.1 理解 Vxe-table 的列结构
Vxe-table 支持三种列类型:
vxe-column: 普通列,对应最终的一列数据。vxe-colgroup: 列分组,用来包裹多个vxe-column或者其他vxe-colgroup,形成父级表头。- 嵌套关系:
vxe-colgroup里面可以包含vxe-column或新的vxe-colgroup,这样就形成了多级。
我们的目标,就是用一个 JavaScript 数组(或对象)来模拟这种嵌套结构。这个结构最好能和后端数据库里存的维度配置直接对应上。
2.2 设计动态表头的数据结构
根据原始文章的需求,我们分析一下:
- 第一列固定:比如“日期”,这列是静态的。
- 中间列动态:根据接口返回的“车间”数据动态生成。每个车间下又有“领料数”、“良品数”、“良品率”三个固定的子列。
- 最后一列固定:比如“操作”列。
那么,接口返回的数据结构可以这样设计:
// 模拟接口返回的车间数据
const apiResponse = [
{
section_id: 1,
section_name: '钢化车间',
// 可能还有其他业务字段...
},
{
section_id: 2,
section_name: '清洗车间',
},
{
section_id: 3,
section_name: '检验车间',
}
];
但是,仅仅有这个还不够,我们需要把它转换成 Vxe-table 能直接用于渲染表头的列配置。一个更通用的做法是,构建一个“列配置数组”。对于上面这个案例,我们可以这样构建:
computed: {
// 动态表头列配置
dynamicHeaderColumns() {
const sections = this.apiData; // 假设从接口获取的数据存在 this.apiData 里
if (!sections || sections.length === 0) {
return [];
}
// 将车间数据映射为 vxe-colgroup 的配置格式
return sections.map(section => {
return {
// 这些属性会直接绑定到 vxe-colgroup 上
title: section.section_name, // 分组标题(车间名)
width: 300, // 整个车间的总宽度
children: [ // 关键!children 属性定义该分组下的子列
{
title: '领料数',
field: `section_${section.section_id}_receive_num`, // 字段名需要唯一且与数据对应
width: 100,
showOverflow: true
},
{
title: '良品数',
field: `section_${section.section_id}_good_num`,
width: 100,
showOverflow: true
},
{
title: '良品率',
field: `section_${section.section_id}_good_rate`,
width: 100,
showOverflow: true,
formatter: ({ cellValue }) => cellValue != null ? `${cellValue}%` : ''
}
]
};
});
}
}
你看,我们生成了一个 dynamicHeaderColumns 数组,每个元素描述一个 vxe-colgroup。这个对象里有 <


355

被折叠的 条评论
为什么被折叠?



