场景
1、目前存在页面是动态路由权限,当用户没有项目页面权限,从漏洞页面有push到项目页面的函数,
点击会直接到首页(根据路由匹配 { path: '*', redirect: '/' })
2、目前我们想做的是在跳转过去的时候添加一个 无权限的提示
Message.error('当前页面无权限'),然后再跳转到首页
3、思路:
进入路由时,查看当前进入的页面路由是否在路由列表中存在
4、方法:
全局路由前置守卫+router的api(getRoutes())
5、注意事项:
我们只能根据path路径进行对比
原因由于是addroute添加的动态路由,当我们在动态路由页面刷新时,第一次路由守卫还没有添加动态路由,
获取的不到route的name等数据,如下图
实现
1、去除默认匹配规则
// 项目去除掉以下代码 我们在全局守卫中自己实现跳转
{ path: '*', redirect: '/' }
2、全局路由前置守卫中对当前路由进行匹配判断
封装路由匹配函数:
比如 path:'/role/detail/2'和route:'/role/detail/:id' 比较(返回true)
function matchPath(path: any, route: any) {
const pathParts = path.split('/')
const routeParts = route.split('/')
if (pathParts.length !== routeParts.length) {
return false
}
for (let i = 0; i < routeParts.length; i++) {
if (routeParts[i] === '*') {
return true
} else if (routeParts[i].startsWith(':')) {
// Handle path parameters
continue
} else if (pathParts[i] !== routeParts[i]) {
return false
}
}
return true
}
匹配判断
let reloadNum = 0
router.beforeEach(async (to: any, from: any, next: any) => {
Nprogress.start()
if (!getToken() && !isWhiteList(to.path)) {
next('/login')
return
}
if (!getToken() && isWhiteList(to.path)) {
next()
return
}
// 获取动态路由
if (getToken() && !store.getters.userInfo) {
try {
await store.dispatch('user/getUserInfo')
// 这一步是在vuex中调取了当前的动态路由,实现router.addrouters
} catch (e) {
await store.dispatch('user/logOut')
}
}
console.log('动态路由页面刷新,由于路由重制,addroute刚添加', to)
// 判断当前路由path和route是否相等!!!!
// 这一步放在动态路由添加后
// 1、获取当前用户完整的路由列表
const routerArr = router.getRoutes()
// 2、判断当前进入的页面to.path是否在路由列表中
const routerIndex = routerArr.findIndex((item: any) => {
return matchPath(to.path, item.path)
})
if (routerIndex === -1) {
// 中英文提示无权限
Message.error(i18n.t('message.quanxian') as string)
// 回到首页
next('/')
return
}
if (getToken() && to.path === '/login') {
next({ name: 'dashboard' })
return
}
if (getToken()) {
if (reloadNum) {
next()
} else {
reloadNum++
next({ ...to, replace: true })
}
return
}
})
方法二:使用path-to-regexp
简单介绍
在vue-router中,react-router或koa-router中,我们经常做路由匹配像这种格式的 /foo/:id 这样的,
或者其他更复杂的路由匹配,都能支持,那么这些路由背后是怎么做的呢?
其实它就是依赖于 path-to-regexp.js的。
import { pathToRegexp } from 'path-to-regexp'
const routerArr = router.getRoutes()
const routerIndex = routerArr.findIndex((item: any) => {
return pathToRegexp(item.path).exec(to.path)
// 匹配正确显示object信息
// 匹配不到返回null
})
if (routerIndex === -1) {
Message.error(i18n.t('message.quanxian') as string)
next('/')
return
}