Vue 项目权限控制
刀刀
0字
0分钟
2026/8/16
后端返回路由规则 ※
后端返回权限控制的一般步骤:
- 用户登录
- 根据用户
userid获取对应菜单 - 规则化格式(根据数据生成合适的路由规则)
- 添加动态路由(使用
addRoute) - 记录
state
登录获取,格式化数组
新建 perssion.js 文件,用于动态设置路由规则。
获取后端返回的路由数据并格式化。后端返回的数据通常是数组对象,每一项包含 name、path 与 component,值都是字符串。而前端路由 component 需要 import(),因此需要格式化转换。
- 首先调用接口获取数据
- 遍历返回的数据数组,格式化
component - 动态添加到
router内
js
let routeArr = []
function parseRoute(arr) {
// 返回一个 Promise,后续异步获取数据
return new Promise((resolve) => {
arr.forEach((item) => {
let newItem = Object.assign({}, item)
let str = item.component
newItem.component = () => {
// return require([`@/views${str}`])
return import(`@/views${str}`)
}
routeArr.push(newItem)
})
return routeArr
})
}
if (如果有用户id) {
// 把数据保存到state中
axios.get('接口').then((res) => {
let newArr = parseRoute(res.data.data)
commit('SET_ROUTES', newArr)
})
}注意
格式化
component时不能先赋值给字符串变量再放进去,如:jslet str = `@/views${item}` return import(str)这样会报错。
低版本不支持
import时,可使用require替代:jsreturn require([`@/views${str}`])格式化时必须用
@/views拼接,不能后端返回/views/page后前端直接采用:jsreturn import(`@${str}`)这样会报错。
导航守卫,动态添加
js
const routerArr = store.state.login.routerArr
router.beforeEach(async (to, from, next) => {
const token = Cookies.get('token')
if (token) {
if (to.path === '/login') {
next('/')
} else {
// 判断是否发请求获取路由规则
if (routerArr.length == 0) {
// 没有,掉请求
const _routerArr = await store.dispatch('getRouter')
_routerArr.forEach((item) => {
router.addRoute(item)
})
next(to.path) // 继续跳转
} else {
// 有了,判断当前用户是否有该路由的权限
if (to.matched.length !== 0) {
next() // 有直接跳转
} else {
next(from.path) // 没有返回来的页面
}
}
}
} else {
// 未登录,判断是否在白名单内
if (whileList.indexOf(to.path) !== -1) {
next() // 在白名单内,可以访问
} else {
next('/login') // 不在白名单内,返回登录页
}
}
})注意
老版本可使用 addRoutes() 放入路由数组;新版已弃用,只能使用 addRoute() 放入单个路由对象,需遍历数组。
js
let arr = [
{
name: 'page',
path: '/page',
component: () => import(''),
},
]
arr.forEach((item) => {
router.addRoute(item)
})重置路由
路由守卫中通过路由规则数组长度判断是否已获取数据,若有则不再请求接口。因此用户登出再登录其他账号时,路由规则仍是旧数据。
解决方法:路由规则保存在 Vuex 内,用户登出时将 Vuex 内的路由规则数组清空,并重置路由为初始状态即可。
js
export function resetRoute() {
const newRouter = new VueRouter({
routes: initRoutes,
})
router.matcher = newRouter.matcher
}总结
- 判断用户是否登录:未登录时判断目标页面是否在白名单内,在则跳转,不在则跳转登录页。
- 用户已登录后判断是否已获取权限数据:若已有,则直接判断目标路由是否有权限,有则跳转,无则提示无权限并返回上一页。
- 若未获取权限数据,则调用
store内的action函数获取数据,返回Promise对象,通过addRoute动态添加路由。 - 用户登出时清空本地存储与 Vuex 内保存的数据数组,获取最新路由状态重新设置路由权限。
按钮权限
获取用户的按钮权限数组,例如:
js
getCode() {
// ['BUY', 'SALE']
}页面中获取 state 保存的权限,判断是否存在即可。
前端控制
后端未配置时,前端可在路由数组内通过 meta 属性写死权限,例如:
js
const initRoutes = [
{
path: '/',
name: 'Home',
component: () => import('@/views/home'),
meta: {
whileList: ['admin', 'test01'],
},
},
]在前置守卫中通过 to.meta.whileList.includes() 判断当前用户是否有该权限即可。