如何使用MUI X Data Grid Pro实现多级树形网格?
问题描述
我正在开发项目,需使用MUI X Data Grid Pro实现多级树形网格,要求每个层级拥有独立列:顶层展示请求通用详情(REQ NO、REQ DATE、ACCESSIONS、NOTES),嵌套层级展开后显示订单详情(ORDER ID、LINE ID、ASSET、DELIVERY)。已配置treeData并使用getTreeDataPath函数,但不知如何正确设置列以展示不同层级,需解决:
- 如何配置DataGridPro让各层级显示对应列?
- 如何确保展开行时嵌套列正确显示?
解决方案
核心思路是动态控制列的可见性,结合行的层级(depth)切换显示的列组。以下是具体实现步骤:
1. 修正数据结构与getTreeDataPath
Data Grid的treeData更适配扁平化带parentId的数据格式,先将嵌套的children结构转换为扁平化数组,并补充层级相关字段:
// 扁平化嵌套数据,添加parentId和depth字段 const flattenRows = (rows, parentId = null, depth = 0) => { return rows.flatMap(row => { const flatRow = { ...row, parentId, depth }; delete flatRow.children; // 移除嵌套的children字段 return [flatRow, ...(row.children ? flattenRows(row.children, row.id, depth + 1) : [])]; }); }; // 处理原始数据 const originalRows = [ { id: 1, reqNo: 123, reqDate: '27/03/22', accessions: 'prateek', notes: 'req', children: [ { id: 2, orderId: 1237, lineId: 2, asset: 'Asset A', delivery: 'Done', }, ], }, ]; const flatRows = flattenRows(originalRows); // 正确的getTreeDataPath函数,返回行的层级路径 const getTreeDataPath = (row) => { const path = []; let currentId = row.parentId; while (currentId) { path.unshift(currentId); const parentRow = flatRows.find(r => r.id === currentId); currentId = parentRow?.parentId; } return path; };
2. 合并列定义并动态控制可见性
将顶层列和嵌套列合并,通过columnVisibilityModel结合行展开状态控制列的显示:
import * as React from "react"; import { DataGridPro, GridColDef, useGridApiRef, gridRowExpansionModelSelector, } from "@mui/x-data-grid-pro"; import Box from "@mui/material/Box"; // 合并所有列定义 const allColumns: GridColDef[] = [ // 顶层列 { field: "reqNo", headerName: "REQ NO", width: 150 }, { field: "reqDate", headerName: "REQ DATE", width: 150 }, { field: "accessions", headerName: "ACCESSIONS", width: 150 }, { field: "notes", headerName: "NOTES", width: 200 }, // 嵌套列 { field: "orderId", headerName: "ORDER ID", width: 150 }, { field: "lineId", headerName: "LINE ID", width: 150 }, { field: "asset", headerName: "ASSET", width: 150 }, { field: "delivery", headerName: "DELIVERY", width: 150 }, ]; // 初始列可见性:仅显示顶层列 const initialVisibility = { reqNo: true, reqDate: true, accessions: true, notes: true, orderId: false, lineId: false, asset: false, delivery: false, }; export default function RequisitionsPage() { const [columnVisibilityModel, setColumnVisibilityModel] = React.useState(initialVisibility); const apiRef = useGridApiRef(); // 监听行展开/折叠事件,更新列可见性 React.useEffect(() => { const expansionModel = gridRowExpansionModelSelector(apiRef); const hasExpandedRows = Object.values(expansionModel).some(Boolean); if (hasExpandedRows) { // 展开时显示所有列 setColumnVisibilityModel({ ...initialVisibility, orderId: true, lineId: true, asset: true, delivery: true, }); } else { // 折叠时仅显示顶层列 setColumnVisibilityModel(initialVisibility); } }, [apiRef]); return ( <Box sx={{ width: "100%" }}> <Box sx={{ height: 300, pt: 1 }}> <DataGridPro apiRef={apiRef} treeData rows={flatRows} columns={allColumns} getTreeDataPath={getTreeDataPath} columnVisibilityModel={columnVisibilityModel} defaultGroupingExpansionDepth={1} /> </Box> </Box> ); }
3. 精细层级控制(可选)
如果需要严格限制仅对应层级显示对应列内容,可以通过renderCell结合行的depth字段实现:
// 修改列定义,添加renderCell判断层级 const allColumns: GridColDef[] = [ { field: "reqNo", headerName: "REQ NO", width: 150, renderCell: (params) => params.row.depth === 0 ? params.value : null }, { field: "reqDate", headerName: "REQ DATE", width: 150, renderCell: (params) => params.row.depth === 0 ? params.value : null }, // 其他顶层列同理 { field: "orderId", headerName: "ORDER ID", width: 150, renderCell: (params) => params.row.depth > 0 ? params.value : null }, // 其他嵌套列同理 ];
关键说明
- 扁平化数据并补充
parentId和depth,能让Data Grid的树形结构渲染更稳定。 - 动态切换
columnVisibilityModel是实现不同层级显示不同列的核心,可根据业务需求调整展开/折叠时的列显示规则。 - 结合
depth和renderCell能实现更精准的内容渲染控制,确保每个层级只展示对应字段。
内容的提问来源于stack exchange,提问作者Yousuf Khan
相关产品推荐
相关产品推荐

