刚换了一家公司,一直以来都没有更新,sorry,最近一直在学习新的前端技术。今天我要分享的是umi权限控制,目前给到了dva方法都比较好,但是每个公司的路由权限控制也是不一样的,所以要根据具体的项目情况进行分析
方法1:app.ts的内置函数patchRouter处理
app.ts 首先,我们在内置方法render去拿权限接口
export async function render(oldRender
) {
const authRoutesResult
= await getUserAuth();
window
.oldRender = () => {
if (authRoutesResult
&& authRoutesResult
.ret
.code
=== 'SUCCESS') {
authRoutes
= authRoutesResult
.data
;
} 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})
}, {'/welcome':true, '/':true, '/login':true})
routes
[0].routes
= filterRoute(routes
[0].routes
, authMap
)
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'
},
相关文章:
umi / inital-state umi / access