动态路由:实际路径和路由参数路径匹配
场景
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 }