vue权限路由控制,vue前端权限管理如何实现
一开始我以为vue路由只能用在工程项目上,其实不然。下面文章主要介绍前端协同后端实现Vue路由权的相关信息。通过示例代码非常详细的介绍,有需要的朋友可以参考一下。
目录
前言实施想法代码实施登录本地路由表生成路由安装路由摘要
前言
在开发管理后台,会有多个角色登录。成功登录后,不同的角色会显示不同的菜单路径。这就是我们通常所说的动态路由授权。实现路由授权的方案有很多。比较常用的有前端使用addRoutes(V3版改为addRoute)动态挂载路由和服务器返回可访问路由菜单。上一篇文章讲了航权的纯前端实现。没看过的可以点击文章链接纯前端实现Vue路由权。今天基于后端路由菜单,实现了路由权限功能。
实现思路
后端路由菜单主要是我们登录后,后端界面会直接返回当前用户可访问的完整路由菜单,相当于前端基于RBAC模型筛选出前端可访问的路由表。
需要注意的是,后端返回的路由菜单不包括登录、404等页面。前端还是需要写一个完整的路由表,根据后端返回的可访问路由菜单筛选出需要挂载到路由器上的路由表。
代码实现
登录
首先,登录。成功登录后,服务器将返回登录用户可访问的路由菜单用户菜单。我们通常会将这些信息保存到Vuex中。
登录方法:
常量登录=()={
ruleFormRef.value?validate((valid: boolean)={
如果(有效){
store . dispatch( user module/log in ,{.帐户表单})
}否则{
console.log(错误提交!)
}
})
}
Vuex对应于异步操作:
异步登录({ commit },有效负载:IRequest) {
//登录获取令牌
const { data }=await accountLogin(有效负载)
提交( SET_TOKEN ,data.token)
localCache.setCache(token ,data.token)
//获取用户信息
const userInfo=await get userInfo(data . id)
提交( SET_USERINFO ,userInfo.data)
localCache.setCache(userInfo ,userInfo.data)
//获取菜单
const user menu=await get user menu(userinfo . data . role . id)
提交( SET_USERMENU ,userMenu.data)
localCache.setCache(userMenu ,userMenu.data)
router . replace(/主/分析/仪表板)
},
接口返回的路由菜单信息:
路由菜单
正如你所看到的,返回的用户菜单是一个数组,它包含了重要的信息,如图标图标,路由名称名称,路由地址,子路由,路由类型等。前面的信息主要用来遍历生成页面左侧的菜单列表,路由类型用来筛选出路由器上需要挂载的路由列表。
本地路由列表
前端还是需要在这里写一个完整的路由表。我准备在router/index.ts里面写界面不返回的菜单,比如登录,404等页面。将接口可能返回的菜单单独放在router/main下。
路由器/索引. ts:
从“vue-router”导入{ createRouter,createWebHashHistory,RouteRecordRaw }
常量路由:RouteRecordRaw[]=[
{
路径:“/”,
重定向:“/main”
},
{
路径:“/login”,
名称:登录,
component:()=import( @/views/log in/index . vue ),
元:{
标题:“登录”
}
},
{
路径:“/main”,
名称:主,
重定向:“/主/分析/仪表板”,
component:()=import( @/views/main/index . vue ),
元:{
标题:“核心技术”
}
},
{
路径:“/:pathMatch(。*)*,
名称:“未找到”,
组件:()=import(@/views/404.vue ),
元:{
标题:“找不到页面~”
}
}
]
路由器/主菜单下面是所有菜单的列表:
单一菜单内容,如dashboard.ts:
const dashboard=()=import( @/views/main/analysis/dashboard/dashboard . vue )
导出默认值{
路径:“/主/分析/仪表板”,
名称:“仪表板”,
组件:仪表板,
元:{
标题:“商品统计”
},
儿童:[]
}
整个路由器目录:
路由器目录
接下来我们需要根据userMenus过滤我们在router/main下写的路由,也就是接口返回的菜单列表对应一个路由表,然后在路由器上挂载路由表,这样我们就可以访问路由了。
生成路由
现在我们需要根据用户菜单生成相应的路线。
首先,我们需要加载所有的路由,也就是router/main下的路由文件的内容。这里我使用require.context方法加载所有的路由。
下面简单介绍一下require.context的api:
require.context是webpack的一个api。通过执行require.context()函数,可以获得指定文件夹中的特定文件。对于需要从同一个文件夹多次导入的模块,可以使用该功能自动导入,而不是使用每次显示的写导入。
require.context(directory,useSubdirectories,regExp)必需参数:
Directory:要搜索的文件的相对路径use子目录:是否查询其子目录regExp:与基本组件的文件名匹配的正则表达式。我们将通过这个api加载router/main下的路由。
const route files=require . context(./router/main ,true,/。ts/)
我们打印路线文件:
路由文件
获取一个对象,我们需要遍历这个对象来获取文件内容:
routeFiles.keys()。forEach((key)={
const route=require(./router/main key.split( . )[1]).系统默认值
console.log(路由)
allRoutes.push(路线)
})
打印路线。
途径
这样,我们得到所有的路线,并把它们放入allRoutes。
接下来,我们需要根据用户菜单获取需要添加的路由。
我们在开头提到了路由类型。该字段主要用于区分菜单下是否有子菜单。1表示有子菜单,2表示没有子菜单。
界面返回的菜单
我们遍历所有路由,然后将其与接口返回的菜单列表userMenus中的路径进行比较。如果相同,就是匹配,那么我们就需要这条路线,否则,我们就过滤掉。因为allRoutes下的每一项都可能有子路由,所以我们还需要在这里执行递归过滤。具体方法如下:
const _ recurseGetRoute=(menus:any[])={
for(菜单的常量菜单){
if (menu.type===2) {
const route=all routes . find((route)=route . path===menu . URL)
如果(路线)路线。推(路线)
}否则{
_recurseGetRoute(menu.children)
}
}
}
最后,routes是对应于userMenus的路由列表。
用于生成相应路线的逻辑安排如下:
从“vue路由器”导入{ RouteRecordRaw }
导出函数generate routes(user menus:any[]):RouteRecordRaw[]{
const routes:RouteRecordRaw[]=[]
//1.首先加载所有默认路由。
const all routes:RouteRecordRaw[]=[]
const route files=require . context(./router/main ,true,/。ts/)
routeFiles.keys()。forEach((key)={
const route=require(./router/main key.split( . )[1]).系统默认值
console.log(路由)
allRoutes.push(路线)
})
//2.根据菜单获取要添加的路线。
//用户菜单:
//type===1 - children - type===1
//type===2 - url - route
const _ recurseGetRoute=(menus:any[])={
for(菜单的常量菜单){
if (menu.type===2) {
const route=all routes . find((route)=route . path===menu . URL)
如果(路线)路线。推(路线)
}否则{
_recurseGetRoute(menu.children)
}
}
}
_recurseGetRoute(用户菜单)
返回路线
}
挂载路由
最后,我们需要在路由器上安装我们得到的路由。
还是说登上路线的时间会被全球路线卫士放在这里?我们将在路由器文件夹下创建一个permission.ts,用来写全局路由守护相关的逻辑:
从 @/router 导入路由器
从“vue路由器”导入{ RouteLocationNormalized }
从“@/utils/cache”导入localCache
从“NProgress”导入nprogress
导入 nprogress/nprogress.css
从“@/store”导入商店
nprogress . configure({ show spinner:false })
const白名单=[/login]
const user menu=store . state . user module . user menu
路由器. beforeEach(
异步(
to: RouteLocationNormalized,
出发地:RouteLocationNormalized,
下一个:任何
)={
document.title=to.meta.title作为字符串
const token:string=local cache . get cache( token )
NProgress.start()
//确定用户是否登录。
if (token) {
if (to.path===/login) {
//如果已经登录,准备进入登录页面,重定向到首页。
下一步({路径:/ })
NProgress.done()
}否则{
store . dispatch( routes module/generate routes ,{ userMenu })
//确保添加路由已完成
//Set replace: true,这样导航就不会留下历史。
下一个({.到,替换:true })
}
}否则{
//如果没有令牌
if(白名单.包含(收件人路径)){
//如果在免登录白名单里,直接输入。
下一个()
}否则{
//其他没有访问权限的页面将被重定向到登录页面
下一步(/login )
NProgress.done()
}
}
}
)
router.afterEach(()={
NProgress.done()
})
routesModule文件下的代码:
//引入generateRoutes
从“@/utils/generateRoutes”导入{ generateRoutes }
动作:{
generateRoutes({ commit },{ userMenu }) {
const routes=generateRoutes(用户菜单)
//set routes=router . main . children
routes.forEach((route)={
Router.addRoute(main ,route)
})
}
}
这样就完成了完整的路由许可功能。我们可以看看这个页面:
系统接口
总结
相比纯粹前端实现路由权,这种基于后端返回路由菜单的方式会更简单。我们不需要过滤出用户可以通过RBAC访问的路线,而是直接将界面返回给我们。我们只需要从路由菜单中生成一条路由,然后挂载该路由。
关于前端配合后端实现Vue路由权的这篇文章到此为止。关于后端实现Vue路由权的更多信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。