tree组件的halfChecked值应该后端存储还是前端计算?
背景
昨天在做一个树形组件权限控制的功能,包括菜单和按钮的访问权限。
熟悉 ant design 组件库 tree 组件的都知道,如果一个父节点,他的子节点存在未选中的,那么这个父节点应该是一个半选(半选可以直观表示其子节点存在未选中)的状态。
1 | const treeData = [ |
如果节点 0-0-0-0
未选中,那么此时实际权限为 ['0-0-0-1', '0-0-0-2', '0-0-0', '0-0']
,tree 组件为了父节点显示为半选效果,tree.checkedKeys
应该为 ['0-0-0-1', '0-0-0-2']
tree
组件 onCheck 事件可以得到 checkedKeys: ['0-0-0-1', '0-0-0-2']
和 halfCheckedKeys: ['0-0-0', '0-0']
最简单的方案是前端传一个实际权限数组 permissionsList
和一个过滤掉半选状态的数组 filteredCheckedKeys
给后端,后端再返回给前端做回显即可。如下
1 | const permissionsList = [...checkedKeys, ...halfCheckedKeys]; |
问题来了,后端觉得没必要保存两个字段,他只希望接收 permissionsList
。后端如果不处理,只能前端计算 filteredCheckedKeys
。
考虑到用户量和权限树节点比较少,前端算就前端算,chatGpt 三下五除二就搞定
1 | // Function to recursively calculate halfCheckedKeys |
到此,前端多了一步计算 getHalfCheckedKeys, 后端少存了一个字段。
但我不想就此结束,可以前端写,但前端不能没理由的写,于是我问了 chatgpt 两个方案的差异,如下:
总结对比
特性 | 前端动态计算 halfCheckedKeys |
后端存储 halfCheckedKeys |
---|---|---|
性能 | 对大树结构可能性能较差 | 性能较好,前端无需计算 |
实现复杂度 | 前端需要复杂的递归计算 | 后端存储和同步逻辑复杂 |
一致性 | 基于前端状态,完全一致 | 依赖于前后端的状态同步 |
灵活性 | 可随时重新计算,无需后端依赖 | 必须依赖后端返回,灵活性较低 |
维护成本 | 代码复杂且随应用增长增加维护难度 | 增加存储和同步逻辑,前后端需同时维护 |
数据管理 | 前端本地管理,无需后端存储 | 后端需存储和管理 halfCheckedKeys |
适用场景
方案一(前端动态计算)适用于
- 权限树结构较小、节点较少时。
- 前端有足够的性能来处理权限树。
- 需要高交互性、即时反馈的场景,减少与后端的交互次数。
方案二(后端存储)适用于
- 权限树结构非常庞大、节点数量较多时。
- 前端性能较低或应用规模较大,减少前端计算压力。
- 希望减少前端逻辑复杂度,后端统一管理和处理数据的场景。
最佳实践
- 如果权限树数据规模较大,或者操作频繁,方案二(后端存储
halfCheckedKeys
)会更具优势,提升前端性能和简化实现。 - 如果权限树较小或者需要灵活性、即时反馈,方案一(前端动态计算)可能更适合,并且减少了后端的复杂性。
后面又聊着聊着,后端也发现了还是后端存储这种方案会比较简单。如果这个权限树节点很多,getHalfCheckedKeys 的计算可能会导致前端页面卡顿。