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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:55:07