欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 使用 react-org-tree 实现卡片模式组织架构图

使用 react-org-tree 实现卡片模式组织架构图

2025/4/24 17:59:09 来源:https://blog.csdn.net/weixin_43172311/article/details/147399443  浏览:    关键词:使用 react-org-tree 实现卡片模式组织架构图

在现代企业管理系统中,组织架构图是一个常见且重要的功能模块。本文将分享如何使用 react-org-tree 组件库实现一个卡片模式的组织架构图,并解决在使用过程中遇到的 expand 展开固定层级的问题。

在这里插入图片描述


项目背景

在开发企业管理系统时,我们需要展示一个清晰的组织架构图,让用户能够直观地了解公司的部门结构和人员分布。传统的树形结构虽然直观,但缺乏交互性和信息展示能力。因此,我们决定采用卡片模式来展示组织架构,每个节点以卡片形式呈现,包含更多详细信息。

技术选型

我们选择了 react-org-tree 组件库来实现组织架构图,主要基于以下几点考虑:

  • 纯 React 实现:与我们的技术栈完美契合
  • 丰富的配置选项:支持横向/纵向布局、可折叠等特性
  • 良好的扩展性:可以通过自定义节点渲染实现个性化需求

效果图

在这里插入图片描述


实现过程

1. 数据准备与转换

首先,我们需要将后端返回的组织数据转换为 react-org-tree 所需的格式。原始数据结构如下:

[{"id": 0,"name": "公司总部","expand": true, // 默认展开一级组织"children": [{"id": 1,"name": "技术部","children": [...]},{"id": 2,"name": "市场部","children": [...]}]}
]

我们编写了 flattenData 函数来转换数据格式:

const flattenData = (data) => {return data?.map((item) => {const newItem = {...item,// 自定义节点渲染label: labelDiv({id: item.id,pid: item.pid,name: item.name,type: item.type,})}// 递归处理子节点if(Array.isArray(newItem.children) && newItem.children.length > 0) {newItem.children = flattenData(newItem.children);}return newItem;})
}

2. 自定义节点渲染

为了在节点中展示更多信息,我们使用了 Ant DesignCard 组件来自定义节点渲染:

const labelDiv = (record) => (<Cardkey={`card${record.id}`}size="small"title={<div className="word-ellipsis" title={record.name}><ClusterOutlined />{record.name}</div>}hoverable={!(record.id===0 || exceptDept.includes(record.id))}className="card-item"onClick={() => enterDetail(record)}>{/* 根节点特有操作 */}{record.id===0 &&<div className="item-info"><div className="info-btn" style={{marginTop: 0}}><Buttontype="link"size="small"onClick={() => handleAddOrg(record)}>新增子组织</Button></div></div>}{/* 普通节点操作按钮 */}{record.id!==0 &&<div className="item-info"><span className="org-type"><span style={{color:"#00000080"}}>组织类型:</span><span title={record.type}>{record?.type || "--"}</span></span><span className="org-type"><span style={{color:"#00000080"}}>责任人:</span><span>{handleUserName(record.real_name, record.username) || "--"}</span></span><div className="info-btn"><Buttontype="link"size="small"onClick={(e) => {e.stopPropagation();handleAddOrg(record);}}>新增</Button><Buttontype="link"size="small"onClick={() => enterDetail(record)}>详情</Button><Buttontype="link"size="small"onClick={(e) => {e.stopPropagation();handleEdit(record);}}>编辑</Button><Popconfirmplacement="topRight"title="请确认是否删除?"onConfirm={(e) => {e?.preventDefault();e?.stopPropagation();handleDelete(record);}}onCancel={onCancel}><Buttontype="link"size="small"onClick={onCancel}>删除</Button></Popconfirm></div></div>}</Card>
)

3. 初始化数据与展开控制

在组件挂载时,我们初始化组织架构数据,并尝试设置默认展开状态:

const [data, setData] = useState({});useEffect(() => {if(orgTreeData && orgTreeData[0] && orgTreeData[0].id===0) {let tempData = {id: orgTreeData[0]?.id,expand: true, // 这里尝试设置展开状态label: labelDiv({id: orgTreeData[0]?.id,name: orgTreeData[0]?.name,}),children: flattenData(orgTreeData[0].children)};setData(tempData);}
}, [orgTreeData]);

4. 渲染组织架构图

最后,我们使用 OrgTree 组件渲染组织架构图:

return (<div className="card-list"><OrgTreedata={data}horizontal={true} // 横向布局collapsable={true} // 可折叠expandAll={true} // 尝试全部展开/></div>
)

遇到的问题与解决方案

问题1:expandAll 不生效

现象:设置 expandAll={true} 后,节点并未全部展开。

原因分析:

  1. collapsable={true} 时,expandAll 可能不会生效
  2. 数据初始化方式可能存在问题

解决方案:

  1. collapsable={false} 时,expandAll 会生效,如果需求没有强制要求,可将 collapsable 直接设置为 false
  2. 在数据中 设置 expand 来单独控制元素的展开

问题2:刷新页面数据恢复初始化层级

现象:编辑操作后,组织树会恢复默认层级,不会记录上次操作的曾经

原因分析:

  1. 插件不支持设置类似 expandedKeys 的树形
  2. 可能是插件内部具有bug

解决方案

  • 手动控制数据,在数据中更改 expand 的值 为 true/false

最终实现效果

通过以上调整,我们成功实现了以下功能:

  • 卡片式组织架构展示
  • 每个节点显示详细信息
  • 支持节点展开/折叠
  • 根节点支持新增子组织
  • 普通节点支持增删改查操作

react-org-tree官方文档


总结

使用 react-org-tree 实现卡片模式组织架构图是一个不错的选择,但在实际开发中需要注意以下几点:

  1. 数据结构:确保数据格式符合组件要求
  2. 展开控制:当 collapsable={true} 时,优先使用 expand 而非 expandAll
  3. 自定义渲染:通过 label 属性实现高度自定义的节点展示
  4. 样式调整:根据需求调整节点样式和布局

通过本文的分享,希望能帮助你在项目中更高效地实现组织架构图功能。如果你有更好的实现方式或遇到其他问题,欢迎在评论区交流讨论!


推荐更多阅读内容

echarts绘制3D旋转地球 JavaScript中的对象字段过滤:只保留特定值的字段

JavaScript 嵌套数组扁平化的 5 种核心方案与深度实践指南

你的网站正在裸奔?Lodash原型链污染漏洞引发的“全员恶人“事件

手把手教你用 React 实现可拖拽排序的 Ant Design 表格

深入理解 Ant Design 中 Popconfirm 的 overlayClassName 属性

从JSON过滤到编程范式:深入理解JavaScript数据操作

React表单状态管理深度解析:Form.useWatch与onChange技术选型指南

Ant Design按钮样式深度适配:实现<Button>与<a>标签颜色完美同步

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词