vxe-table vue 表格实现复杂分组列头与数据合并:多级分类与动态合并实战
在商品管理、订单报表等业务场景中,我们常常需要展示多层级分类(如一级分类 → 二级分类 → 三级分类),并希望将相同分类的数据行纵向合并,让表格结构更清晰、数据层级一目了然。vxe-table 提供了灵活的列头分组(children)和单元格合并(mergeCells)机制,可以轻松实现“复杂表头 + 数据自动合并”的效果。
- 本文将基于一个商品列表示例,详解如何实现:
- 使用多级列头(分类、商品信息、款式)构建复杂表头。
- 通过动态计算 mergeCells,自动按分类层级合并数据单元格,并附带一个通用的合并规则计算器,可复用到任何层级字段。
最终效果预览
- 表头:按“分类”、“商品信息”、“款式”等多级分组,形成清晰的树形表头结构。
- 数据区:根据“一级分类 → 二级分类 → 三级分类”的层级关系,自动合并相同类别的单元格,使同类数据聚合在一起,提升可读性。

代码
- 通过在 columns 中使用 children 属性,可以构建无限层级的树形表头:
- 动态计算 mergeCells 数据合并规则,为了根据数据自动生成合并规则,我们需要一个递归算法:按 categoryLevel1 → categoryLevel2 → categoryLevel3 的顺序,统计相邻行中相同值的连续行数,生成对应的合并单元。
重要前提:数据必须按层级字段排序(如先按一级分类、再按二级分类、再按三级分类),否则相同类别的行不会连续,合并会错乱。
<template>
<div>
<vxe-grid v-bind="gridOptions"></vxe-grid>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const gridOptions = reactive({
height: 1000,
border: true,
loading: false,
columnConfig: {
resizable: true
},
mergeCells: [
{ row: 0, col: 0, rowspan: 17, colspan: 1 },
{ row: 0, col: 1, rowspan: 9, colspan: 1 },
{ row: 0, col: 2, rowspan: 3, colspan: 1 }
],
columns: [
{
title: '分类',
children: [
{ field: 'categoryLevel1', title: '一级分类', width: 120 },
{ field: 'categoryLevel2', title: '二级分类', width: 120 },
{ field: 'categoryLevel3', title: '三级分类', width: 120 }
]
},
{
title: '商品信息',
children: [
{ field: 'productName', title: '名称', minWidth: 200 },
{ field: 'sku', title: 'SKU', width: 160 },
{ field: 'price', title: '价格', width: 120 },
{ field: 'quantity', title: '数量', width: 120 },
{ field: 'currency', title: '货币', width: 120 },
{
title: '款式',
children: [
{ field: 'color', title: '颜色', width: 120 },
{ field: 'size', title: '尺寸编码', width: 120 }
]
}
]
},
{ field: 'updateDate', title: '更新时间', width: 120 },
{ field: 'createDate', title: '创建时间', width: 120 }
],
data: []
})
/**
* 通用表格合并规则计算器
* @param {Array} list - 数据数组
* @param {Array} levelKeys - 层级字段名数组
* @returns {Array} mergeCells 数组
*/
const calculateMergeCells = (list, levelKeys) => {
const mergeCells = []
const total = list.length
if (total === 0 || levelKeys.length === 0) {
return
}
const processGroup = (start, col) => {
if (col >= levelKeys.length || start >= total) {
return
}
const key = levelKeys[col]
let end = start
const value = list[start][key]
while (end < total && list[end][key] === value) {
end++
}
mergeCells.push({
row: start,
col: col,
rowspan: end - start,
colspan: 1
})
if (col + 1 < levelKeys.length) {
let i = start
while (i < end) {
const nextKey = levelKeys[col + 1]
const nextValue = list[i][nextKey]
let j = i
while (j < end && list[j][nextKey] === nextValue) {
j++
}
processGroup(i, col + 1)
i = j
}
}
}
let i = 0
while (i < total) {
const key = levelKeys[0]
const value = list[i][key]
let j = i
while (j < total && list[j][key] === value) {
j++
}
processGroup(i, 0)
i = j
}
return mergeCells
}
const loadList = () => {
gridOptions.loading = true
setTimeout(() => {
const list = [
{ id: 10001, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: 'T恤', productName: '纯棉T恤M894', sku: '2345346546', price: 998, quantity: 32, color: '黑色', size: 'XL', currency: 'rmb', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10002, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: 'T恤', productName: '印花T恤J78', sku: '5676575677567', price: 1203, quantity: 42, color: '红色', size: 'M', currency: 'rmb', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10003, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: 'T恤', productName: '圆领T恤V56', sku: '768768678686', price: 123, quantity: 12, color: '白色', size: 'L', currency: 'rmb', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10004, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: '羽绒服', productName: '薄款羽绒服E1243', sku: '4234324324324', price: 300, quantity: 78, color: '灰色', size: 'XXXL', currency: 'usd', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10005, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: '羽绒服', productName: '厚款羽绒服T56435', sku: '435438797', price: 200, quantity: 60, color: '白色', size: 'XXL', currency: 'usd', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10006, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: '短袖', productName: '印花短袖O76', sku: '1232138908900', price: 425, quantity: 86, color: '蓝色', size: 'L', currency: 'rmb', updateDate: '2026-03-05', createDate: '2026-03-20' },
{ id: 10007, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: '短袖', productName: '运动短袖R45', sku: '23454654356889', price: 125, quantity: 77, color: '紫色', size: 'XXXXL', currency: 'usd', updateDate: '2026-11-05', createDate: '2026-11-20' },
{ id: 10008, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: '短袖', productName: '速干短袖R45', sku: '7802354345568', price: 255, quantity: 66, color: '橙色', size: 'L', currency: 'rmb', updateDate: '2026-10-05', createDate: '2026-10-20' },
{ id: 10009, categoryLevel1: '服装', categoryLevel2: '男装', categoryLevel3: '长袖', productName: '纯棉长袖Y7f', sku: '23434665787097', price: 236, quantity: 85, color: '白色', size: 'XXXL', currency: 'usd', updateDate: '2026-02-03', createDate: '2026-02-03' },
{ id: 10010, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: 'T恤', productName: '纯棉T恤C583', sku: '43543556797234', price: 758, quantity: 12, color: '灰色', size: 'L', currency: 'rmb', updateDate: '2026-09-05', createDate: '2026-09-20' },
{ id: 10011, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: 'T恤', productName: '超短T恤K847', sku: '54367567809081243', price: 468, quantity: 14, color: '红色', size: 'XXXL', currency: 'usd', updateDate: '2026-11-02', createDate: '2026-11-02' },
{ id: 10012, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: '长袖', productName: '纯棉长袖V7854', sku: '34565779800867', price: 568, quantity: 25, color: '白色', size: 'L', currency: 'rmb', updateDate: '2026-12-05', createDate: '2026-12-20' },
{ id: 10013, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: '长袖', productName: '运动款长袖J834', sku: '32443216578090534', price: 369, quantity: 24, color: '紫色', size: 'M', currency: 'rmb', updateDate: '2026-08-05', createDate: '2026-08-20' },
{ id: 10014, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: '长袖', productName: '印花长袖C674', sku: '657897124535400', price: 147, quantity: 65, color: '橙色', size: 'XXXXL', currency: 'rmb', updateDate: '2026-06-07', createDate: '2026-05-27' },
{ id: 10015, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: '羽绒服', productName: '超薄羽绒服C743', sku: '2342344567659345', price: 258, quantity: 34, color: '蓝色', size: 'XXXL', currency: 'usd', updateDate: '2027-06-05', createDate: '2027-05-20' },
{ id: 10016, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: '羽绒服', productName: '特厚羽绒服Z746', sku: '122459800980965', price: 80, quantity: 44, color: '黑色', size: 'XXL', currency: 'rmb', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10017, categoryLevel1: '服装', categoryLevel2: '女装', categoryLevel3: '羽绒服', productName: '超轻羽绒服K847', sku: '324324890435356', price: 60, quantity: 55, color: '灰色', size: 'L', currency: 'rmb', updateDate: '2026-07-05', createDate: '2026-07-20' },
{ id: 10018, categoryLevel1: '家电', categoryLevel2: '冰箱', categoryLevel3: '160升', productName: '160升大冰箱H8764', sku: '34657687934256457', price: 2354, quantity: 77, color: '橙色', size: 'XXL', currency: 'usd', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10019, categoryLevel1: '家电', categoryLevel2: '冰箱', categoryLevel3: '160升', productName: '160升省电冰箱D768', sku: '32454366540901', price: 3250, quantity: 81, color: '白色', size: 'M', currency: 'usd', updateDate: '2026-06-01', createDate: '2026-05-05' },
{ id: 10020, categoryLevel1: '家电', categoryLevel2: '冰箱', categoryLevel3: '90升', productName: '90升小冰箱F456', sku: '1214355460980', price: 1000, quantity: 99, color: '黑色', size: 'XXXXL', currency: 'rmb', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10021, categoryLevel1: '家电', categoryLevel2: '冰箱', categoryLevel3: '90升', productName: '90升便捷冰箱H6754', sku: '948239017423743472', price: 3520, quantity: 97, color: '红色', size: 'XXL', currency: 'usd', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10022, categoryLevel1: '家电', categoryLevel2: '洗衣机', categoryLevel3: '滚筒', productName: '高端滚筒洗衣机H847', sku: '1045671345436577', price: 5060, quantity: 10, color: '橙色', size: 'L', currency: 'rmb', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10023, categoryLevel1: '家电', categoryLevel2: '洗衣机', categoryLevel3: '滚筒', productName: '普通滚筒洗衣机B8743', sku: '12000234645456', price: 3250, quantity: 9, color: '紫色', size: 'XXXXL', currency: 'rmb', updateDate: '2026-09-11', createDate: '2026-09-15' },
{ id: 10024, categoryLevel1: '家电', categoryLevel2: '洗衣机', categoryLevel3: '波轮', productName: '家用波轮洗衣机J984', sku: '3804354351435243', price: 5000, quantity: 19, color: '白色', size: 'XXL', currency: 'usd', updateDate: '2026-08-10', createDate: '2026-08-11' },
{ id: 10025, categoryLevel1: '家电', categoryLevel2: '洗衣机', categoryLevel3: '波轮', productName: '高端波轮洗衣机X8734', sku: '948246547367867802', price: 4000, quantity: 29, color: '红色', size: 'M', currency: 'rmb', updateDate: '2026-10-05', createDate: '2026-10-20' },
{ id: 10026, categoryLevel1: '家电', categoryLevel2: '电视', categoryLevel3: '85寸', productName: '85寸超级电视机G456', sku: '32345450039083456', price: 9000, quantity: 5, color: '紫色', size: 'XXXL', currency: 'usd', updateDate: '2026-06-05', createDate: '2026-05-20' },
{ id: 10027, categoryLevel1: '家电', categoryLevel2: '电视', categoryLevel3: '85寸', productName: '85寸标准电视H874', sku: '890345081232340009', price: 7000, quantity: 37, color: '红色', size: 'M', currency: 'usd', updateDate: '2026-11-10', createDate: '2026-11-22' },
{ id: 10028, categoryLevel1: '家电', categoryLevel2: '电视', categoryLevel3: '80寸', productName: '80寸纳米电视机H763', sku: '213042456456798034', price: 6000, quantity: 3, color: '灰色', size: 'XXL', currency: 'rmb', updateDate: '2026-02-19', createDate: '2026-02-22' },
{ id: 10029, categoryLevel1: '家电', categoryLevel2: '电视', categoryLevel3: '80寸', productName: '80寸超级音质电视机B704', sku: '235768765876584304', price: 5000, quantity: 2, color: '白色', size: 'L', currency: 'rmb', updateDate: '2026-01-05', createDate: '2026-01-20' },
{ id: 10030, categoryLevel1: '家电', categoryLevel2: '电视', categoryLevel3: '65寸', productName: '65寸小电视机V650', sku: '561231234345600', price: 4500, quantity: 14, color: '蓝色', size: 'L', currency: 'rmb', updateDate: '2026-06-20', createDate: '2026-05-28' }
]
gridOptions.mergeCells = calculateMergeCells(list, ['categoryLevel1', 'categoryLevel2', 'categoryLevel3'])
gridOptions.data = list
gridOptions.loading = false
}, 150)
}
loadList()
</script>
配置要点
| 配置项 | 作用 | 本例中的值 |
|---|---|---|
| columns[].children | 构建多级表头 | 分类 → 商品信息 → 款式,共三层 |
| mergeCells | 定义数据单元格合并规则 | 由 calculateMergeCells 动态生成 |
| columnConfig.resizable | 允许用户拖拽调整列宽 | true |
注意事项
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 合并区域错位或重叠 | 数据未按层级字段排序 | 对数据按 levelKeys 顺序排序后再传入。 |
| 部分层级未合并 | levelKeys 未包含该字段 | 检查传入的 levelKeys 数组是否完整。 |
| 合并后某些行显示空白 | rowspan 计算超出数据边界 | 检查 processGroup 中的 end 值是否超过 total。 |
| 表头与数据错位 | children 层级与合并列数不匹配 | 确保 mergeCells 中的 col 索引与 columns 中的叶子列索引对应。 |
| 性能问题(数据量大时卡顿) | calculateMergeCells 递归遍历复杂度较高 | 可在数据加载后单独计算,避免在渲染循环中频繁调用。 |
通过 vxe-table 的多级列头(children)和单元格合并(mergeCells)功能,我们可以轻松实现商品分类等复杂表格的分组展示;这种方法不仅适用于商品分类,还可用于部门组织架构、地区分级等任何需要层级合并的场景。

浙公网安备 33010602011771号