vue表格 vxe-table 实现商品分组列头与数据的类别合并

在商品管理、订单报表等业务场景中,我们常常需要展示多层级分类(如一级分类 → 二级分类 → 三级分类),并希望将相同分类的数据行纵向合并,让表格结构更清晰、数据层级一目了然。vxe-table 提供了灵活的列头分组(children)和单元格合并(mergeCells)机制,可以轻松实现这一效果。

  • 使用多级列头(分类、商品信息、款式)构建复杂表头。
  • 通过动态计算 mergeCells 实现类别列的纵向合并。

实现说明

1. 多级列头(表头分组)

通过在 columns 中使用 children 属性,可以构建无限层级的树形表头:

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 },
      // ... 其他子列
      {
        title: '款式',  // 支持更深层级
        children: [
          { field: 'color', title: '颜色', width: 120 },
          { field: 'size', title: '尺寸编码', width: 120 }
        ]
      }
    ]
  }
]

2. 数据合并规则(动态计算 mergeCells)

mergeCells 数组定义了哪些单元格需要合并,格式为:

{ row: 起始行索引, col: 起始列索引, rowspan: 合并行数, colspan: 合并列数 }

为了根据数据自动生成合并规则,我们需要一个递归算法:按 categoryLevel1 → categoryLevel2 → categoryLevel3 的顺序,统计相邻行中相同值的连续行数,生成对应的合并单元。

代码

image

  • 表头:按“分类”、“商品信息”、“款式”等多级分组。
  • 数据区:根据“一级分类 → 二级分类 → 三级分类”的层级关系,自动合并相同类别的单元格。
<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>

计算规则函数实现

  • 该函数的核心逻辑是递归分组统计:

    • 按第一层级分组:遍历数据,找出 categoryLevel1 相同的连续行范围。
    • 递归深入:在每个分组内部,再按第二层级 categoryLevel2 分组,依次类推。
    • 生成合并规则:每进入一个分组,就生成一条 { row: start, col: 层级索引, rowspan: 行数, colspan: 1 } 记录。
  • 通过 vxe-table 的多级列头(children)和单元格合并(mergeCells)功能,我们可以轻松实现商品分类等复杂表格的分组展示。核心步骤如下:

    • 设计多级列头:使用 children 构建树形表头结构。
    • 准备数据:按层级字段排序。
    • 动态计算合并规则:编写递归函数,根据数据生成 mergeCells 数组。
    • 渲染表格:将 mergeCells 和 data 传入 vxe-grid。
      这种方法不仅适用于商品分类,还可用于部门组织架构、地区分级等任何需要层级合并的场景。

https://vxetable.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值