You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MUI Table/DataGrid中展示多数据并实现数据分组?

MUI 分组表格实现示例

首先,实现这类分组表格的核心是先对原始数据按指定字段做分组处理,再在表格中嵌套渲染分组标题行和对应的子数据行。以下是基于 MUI v5 的具体实现方案:

1. 先做数据分组预处理

把原始数据转换成「分组名: 子数据列表」的结构,方便后续渲染:

// 示例原始数据
const rawData = [
  { id: 1, category: "电子产品", name: "手机", price: 3999 },
  { id: 2, category: "电子产品", name: "笔记本电脑", price: 7999 },
  { id: 3, category: "家居用品", name: "台灯", price: 99 },
  { id: 4, category: "家居用品", name: "抱枕", price: 49 },
];

// 用 reduce 完成分组,也可以用 Lodash 的 groupBy 简化(如果项目已引入)
const groupedData = rawData.reduce((acc, item) => {
  const groupKey = item.category;
  if (!acc[groupKey]) acc[groupKey] = [];
  acc[groupKey].push(item);
  return acc;
}, {});

2. 编写分组表格组件

利用 MUI 的基础表格组件,循环渲染分组标题和子数据行:

import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Typography } from '@mui/material';
import React from 'react';

export default function GroupedTable() {
  return (
    <TableContainer component={Paper}>
      <Table aria-label="分组表格">
        <TableHead>
          <TableRow>
            <TableCell>商品名称</TableCell>
            <TableCell align="right">价格</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {/* 遍历每个分组 */}
          {Object.entries(groupedData).map(([category, items]) => (
            <React.Fragment key={category}>
              {/* 分组标题行:合并单元格+高亮背景 */}
              <TableRow>
                <TableCell 
                  colSpan={2} 
                  sx={{ backgroundColor: '#f5f5f5', paddingY: 1 }}
                >
                  <Typography variant="subtitle1" fontWeight="bold">
                    {category}
                  </Typography>
                </TableCell>
              </TableRow>
              {/* 分组下的子数据行 */}
              {items.map((item) => (
                <TableRow key={item.id}>
                  <TableCell component="th" scope="row">
                    {item.name}
                  </TableCell>
                  <TableCell align="right">{item.price} 元</TableCell>
                </TableRow>
              ))}
            </React.Fragment>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
}

额外扩展:可展开/收起的分组

如果需要点击分组标题展开/收起子行,只需添加状态控制:

// 在组件内添加状态
const [expandedGroups, setExpandedGroups] = React.useState(new Set(['电子产品']));

// 切换分组展开状态的方法
const toggleGroup = (category) => {
  setExpandedGroups(prev => {
    const newSet = new Set(prev);
    if (newSet.has(category)) newSet.delete(category);
    else newSet.add(category);
    return newSet;
  });
};

// 渲染时判断是否展开
{Object.entries(groupedData).map(([category, items]) => (
  <React.Fragment key={category}>
    <TableRow onClick={() => toggleGroup(category)} style={{ cursor: 'pointer' }}>
      <TableCell colSpan={2} sx={{ backgroundColor: '#f5f5f5' }}>
        <Typography variant="subtitle1" fontWeight="bold">
          {expandedGroups.has(category) ? '▼' : '▶'} {category}
        </Typography>
      </TableCell>
    </TableRow>
    {/* 仅渲染展开的分组子行 */}
    {expandedGroups.has(category) && items.map((item) => (
      <TableRow key={item.id}>
        <TableCell component="th" scope="row">
          {item.name}
        </TableCell>
        <TableCell align="right">{item.price} 元</TableCell>
      </TableRow>
    ))}
  </React.Fragment>
))}

内容的提问来源于stack exchange,提问作者CHL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:48:11