React 侧边栏按权限隐藏或显示指定元素的实现问题咨询
侧边栏权限过滤实现方案
前置准备
假设你持有的白名单为允许访问的模块唯一标识集合,示例结构如下:
// 白名单值和每个module/subModule的key一一对应 const permissionWhitelist = new Set(['user-manage', 'order-list', 'data-overview'])
1. 编写模块过滤工具函数
实现递归过滤逻辑,同时处理父模块和子模块的权限校验,子模块全被过滤时父模块也不展示:
// 替换ModuleType为你项目中module对象的实际类型 const filterAllowedModules = (modules: ModuleType[]) => { return modules.filter(module => { // 校验一级模块权限 const isModuleAllowed = permissionWhitelist.has(module.key); if (!isModuleAllowed) return false; // 处理带子模块的可展开项 if (module.subModules?.length) { // 过滤有权限的子模块 const allowedSubModules = module.subModules.filter(subModule => permissionWhitelist.has(subModule.key) ); // 子模块全部无权限时,父模块也隐藏 if (allowedSubModules.length === 0) return false; // 挂载过滤后的子模块供渲染使用 module.filteredSubModules = allowedSubModules; } return true; }) }
如果你的白名单是按路由path匹配,将上述判断逻辑替换为permissionWhitelist.has(module.path)即可。
2. 修改侧边栏渲染逻辑
先过滤模块数组再遍历渲染,可展开项的子列表使用过滤后的子模块生成:
<List> {filterAllowedModules(modules).map(module => ( <Fragment key={module.key}> {module.section && <SidebarSection title={module.section()} />} {module.filteredSubModules?.length ? ( <ExpandableSidebarItem title={module.title()} collapsed={module.collapsed ?? false} onExpand={() => module.collapsed ? dispatch(expandModule(module.key)) : dispatch(collapseModule(module.key))} son={module.filteredSubModules.map(subModule => getSideBarItemFromModule(subModule))} /> ) : ( <SidebarItem title={module.title()} href={module.path} selected={module.key === selectedKey} onListItemClick={() => dispatch(openView(getViewFromModule(module)))} /> )} </Fragment> ))} </List>
常见不生效原因排查
- 仅给module添加了权限标识,未对modules数组执行过滤操作,直接遍历全量数组导致全部展示
- 子模块过滤后未替换原subModules,渲染可展开项时仍使用全量子模块生成子列表
- 白名单为异步接口返回时,未等白名单加载完成就执行过滤逻辑,导致白名单为空过滤不生效
- 未处理子模块全被过滤的场景,出现空的可展开父项
内容的提问来源于stack exchange,提问作者Manuel_dev
相关产品推荐
相关产品推荐

