umi+react动态权限控制

it2025-11-05  12

刚换了一家公司,一直以来都没有更新,sorry,最近一直在学习新的前端技术。今天我要分享的是umi权限控制,目前给到了dva方法都比较好,但是每个公司的路由权限控制也是不一样的,所以要根据具体的项目情况进行分析

方法1:app.ts的内置函数patchRouter处理

app.ts 首先,我们在内置方法render去拿权限接口 export async function render(oldRender) { const authRoutesResult = await getUserAuth(); //拿权限(getUserAuth)是权限接口,里面的参数就是数组包对象的方式 window.oldRender = () => { if (authRoutesResult && authRoutesResult.ret.code === 'SUCCESS') { authRoutes = authRoutesResult.data; //这个authRoutes放在全局定义下 } else { oldRender(); } oldRender(); } if (window.oldRender) { window.oldRender(); } }

下一步在内置的patchRoutes函数根据权限对路由进行处理

export function patchRoutes({routes}) { authMap = authRoutes.reduce((total:any, next: any) => { return ({...total, [next.url]: true}) //authMap全局声明 // 把权限通过健值对的方式存起来,这个根据个人接口情况去处理 }, {'/welcome':true, '/':true, '/login':true}) // 这后面这个是默认每个权限都有的路由 routes[0].routes = filterRoute(routes[0].routes, authMap) // 我们把这个routes替换跳,这个会给到渲染的组件 window.g_routes = routes; } // 对路由进行递归处理,没有权限的过滤掉 function filterRoute(routes,authMap) { const arr:any = []; routes.forEach((elem:any) => { if(authMap[elem.path]) { arr.push({...elem, routes:(elem.routes && elem.routes.length > 0)?filterRoute(elem.routes, authMap):[]}) } }) return arr; }

最后我们把每个页面对应的权限控制通过useMode传到layouts/basicLayout.tsx

export async function getInitialState() { return authMap //上面说了,全局申请直接传就好 } layouts/basicLayout.tsx 我们需要去拿authMap const authMap = useModel('@@initialState')

然后在<ProLayout></proLayout>内部进行判断处理

法二:通过app.ts和access.ts处理

app.ts import { getUserAuth } from './services/user'; import {history} from 'umi' let configRoutes = []; export function patchRoutes({routes}) { configRoutes = routes[0].routes; } export async function getInitialState() { const query = history.location.query; if(query?.token) { localStorage.setItem('User-Token', query.token) } const data = await getUserAuth(); if(data.ret.code !== 'SUCCESS')return; return {...data, routes:configRoutes[1].routes} } access.ts export default function(initialState:any) { let authAccess = { "/homeconfig": false, "/pointlocation": false, "/enumconfig": false, "/detailconfig/": false, "/detailconfig/park": false, "/detailconfig/play": false, "/detailconfig/scenic": false, "/detailconfig/show": false, "/detailconfig/restaurant": false, "/detailconfig/hotel": false, "/detailconfig/shop": false, "/detailconfig/traffic": false, "/configuration": false, "/configuration/tab": false, "/configuration/condition": false, "/cardconfig": false, "/indexnotification": false, "/pointlocation/project": false, "/message": false, "/approve": false, "/operateauthorityconfig": false, "/operateauthorityconfig/supermanger": false, "/operateauthorityconfig/supermanger/config": false, "/operateauthorityconfig/supermanger/order": false, "/operateauthorityconfig/assigningroles": false, "/operateauthorityconfig/ConfigRoles": false, "/operateauthorityconfig/ConfigRoles/add": false, "/operateauthorityconfig/ConfigRoles/edit": false }; const {data, routes} = initialState; const authMap = (Array.isArray(data)?data:[]).reduce((total:any, next: any) => { return ({...total, [next.url]: true}) }, {}) function filterRoute(routers:any) { routers.forEach((elem:any) => { if(!!elem.access && authMap[elem.path]) { authAccess[elem.access] = true; if(elem.routes && elem.routes.length > 0) { filterRoute(elem.routes) } } }) } filterRoute(routes) return authAccess }

注意在config/config.ts的路由routes需要配置access参数,对应的就是authAccess里面的键,如图

layouts/basicLayout.tsx const authAccess = useAccess() 下面组件添加这个 <ProLayout> { (authAccess[history.location.pathname] === false) ? (<div>此页面没有权限</div>) : children } </ProLayout>

这个处理利用的就是路由的access参数,还是不错的,两个方法都行,有什么问题直接留言,一起处理。

补充:添加公共地址,直接跳welcome页面(指欢迎页)

• 需求:有的时候,我们会很自然的在网站后面去加index.html或者/home,需要直接进入首页

• 实现一:在BasicLayout的页面去处理

{ (authAccess[history.location.pathname] === false) ? noAuthority : (['/index.html','/index.htm','/home'].includes(history.location.pathname) ? history.replace('/welcome') : children) } 这种方法是在页面的层次去处理,不是很美观 实现二:在config.ts(或routes.ts)页面去处理 { path: '/(index|index.html|home|index.htm)', redirect: '/welcome' }, // router是支持这种格式的,所以可以直接进行添加处理(是不是更美观了)

相关文章:

umi / inital-state umi / access

最新回复(0)