如何在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
相关产品推荐
相关产品推荐

