如何用ReactJS构建员工-经理层级关系的可展开树形组件?
用React + Material UI实现员工-经理树形结构组件
第一步:将扁平数据转换为树形结构
原始的员工-经理数据是扁平数组,需要先转成嵌套的树形结构,才能适配Tree View组件的渲染逻辑。可以用下面的工具函数处理:
// 转换扁平数据为树形结构 const buildTree = (data) => { const empMap = {}; const tree = []; // 先把所有员工存入映射表,方便后续快速查找 data.forEach(emp => { empMap[emp.emp_id] = { ...emp, children: [] }; }); // 遍历数据,将下属挂载到对应经理的children数组中 data.forEach(emp => { if (emp.manager_id) { empMap[emp.manager_id].children.push(empMap[emp.emp_id]); } else { // manager_id为空的是根节点(最高级经理) tree.push(empMap[emp.emp_id]); } }); return tree; }; // 使用示例 const empTree = buildTree(empMangerData);
第二步:用Material UI Tree View渲染树形结构
1. 安装依赖
先安装Material UI的Tree View相关包:
npm install @mui/material @mui/icons-material @mui/x-tree-view
2. 编写React组件
下面是完整的组件代码,包含状态管理、递归渲染节点、展开/收起逻辑:
import React, { useState } from 'react'; import { TreeView } from '@mui/x-tree-view/TreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; const EmployeeTree = () => { // 原始员工-经理数据 const empMangerData = [ { emp_id: 'EMP001', manager_id: '' }, { emp_id: 'EMP002', manager_id: 'EMP001' }, { emp_id: 'EMP003', manager_id: 'EMP001' }, { emp_id: 'EMP004', manager_id: 'EMP002' }, { emp_id: 'EMP005', manager_id: 'EMP002' } ]; // 控制节点展开状态的state const [expandedNodes, setExpandedNodes] = useState([]); // 转换扁平数据为树形结构 const buildTree = (data) => { const empMap = {}; const tree = []; data.forEach(emp => { empMap[emp.emp_id] = { ...emp, children: [] }; }); data.forEach(emp => { if (emp.manager_id) { empMap[emp.manager_id].children.push(empMap[emp.emp_id]); } else { tree.push(empMap[emp.emp_id]); } }); return tree; }; const empTree = buildTree(empMangerData); // 递归渲染所有树形节点 const renderTreeNodes = (nodes) => { return nodes.map(node => ( <TreeItem key={node.emp_id} nodeId={node.emp_id} label={node.emp_id} > {node.children.length > 0 && renderTreeNodes(node.children)} </TreeItem> )); }; return ( <TreeView expanded={expandedNodes} onNodeExpand={(e) => setExpandedNodes([...expandedNodes, e.target.id])} onNodeCollapse={(e) => setExpandedNodes(expandedNodes.filter(id => id !== e.target.id))} defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronRightIcon />} sx={{ height: 240, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }} > {renderTreeNodes(empTree)} </TreeView> ); }; export default EmployeeTree;
效果说明
组件会渲染出层级分明的员工树形结构:根节点为最高级经理(manager_id为空的EMP001),点击节点可展开/收起下属列表——展开EMP001能看到EMP002、EMP003,展开EMP002能看到EMP004、EMP005,完全匹配你需要的展示效果。
内容的提问来源于stack exchange,提问作者Anonymousss
相关产品推荐
相关产品推荐

