Vue Router beforeEach中使用用户授权函数遇JS方法失效问题
问题描述
我有一个用于用户授权的函数,可限制用户对特定组件的访问,该函数在beforeEnter导航守卫中运行正常,但尝试在router.beforeEach导航守卫中使用时,forEach、includes等JavaScript方法无法正常工作。现需将该授权函数与已有的登录校验条件整合到beforeEach中,实现路由跳转前的权限检查。
原授权函数代码:
function authorizeUser(to) { const currentUser = store.getters["auth/isCurrentUser"]; console.log(currentUser); currentUser.teams.forEach((team) => { const validPermissions = team.permissions.filter((item) => { return to.meta.neededPermissions.includes(item.permissionType); }); //returns array of objects const mappedValidPermissions = validPermissions.map((item) => { return item.permissionType; });// returns array with permissionType // returned matched permissions console.log( JSON.stringify(to.meta.neededPermissions), JSON.stringify(mappedValidPermissions), ); if (!to.meta.neededPermissions.every(i=>mappedValidPermissions.includes(i))) { router.push({ path: "/:notFound(.*)" }); } }); }
原router.beforeEach代码:
router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !store.getters["auth/isLoggedIn"]) { next({ name: "Authentication", params: { desiredRoute: to.fullPath, }, }); } else { next(); } });
解决方案
问题根源
beforeEach中方法失效的核心原因是全局守卫触发时机更早,可能用户数据(currentUser、teams、permissions)还未加载完成,导致调用undefined的数组方法。同时原授权逻辑存在缺陷:遍历每个团队时,只要有一个团队不满足权限就跳404,不符合多团队权限的常见需求(只要有一个团队拥有权限就应允许访问)。
整合步骤与代码
1. 修正授权函数(加空值校验+优化逻辑)
先给授权函数添加空值安全校验,避免报错;同时将逻辑调整为“只要有一个团队满足所有所需权限,就返回有权限”。
2. 整合到全局导航守卫
将登录校验与权限校验按顺序串联,确保先验证登录状态,再检查权限。
整合后的完整代码:
// 修正后的权限校验函数:返回用户是否拥有访问当前路由的权限 function hasRequiredPermissions(to) { const currentUser = store.getters["auth/isCurrentUser"]; // 空值校验:用户未加载或无团队时,直接判定无权限 if (!currentUser || !Array.isArray(currentUser.teams)) { return false; } // 遍历所有团队,只要有一个团队满足全部所需权限,就返回有权限 return currentUser.teams.some(team => { // 空值校验:当前团队无权限列表时跳过 if (!Array.isArray(team.permissions)) return false; // 提取当前团队的所有权限类型 const teamPermissionTypes = team.permissions.map(item => item.permissionType); // 检查路由所需的所有权限是否都在团队权限中 return to.meta.neededPermissions.every(perm => teamPermissionTypes.includes(perm)); }); } // 整合后的全局导航守卫 router.beforeEach((to, from, next) => { // 第一步:登录状态校验 if (to.meta.requiresAuth && !store.getters["auth/isLoggedIn"]) { next({ name: "Authentication", params: { desiredRoute: to.fullPath, }, }); return; // 终止后续逻辑,避免重复调用next() } // 第二步:权限校验(仅对配置了neededPermissions的路由生效) if (to.meta.neededPermissions) { const hasPermission = hasRequiredPermissions(to); if (!hasPermission) { next({ path: "/:notFound(.*)" }); return; } } // 所有校验通过,放行路由 next(); });
关键优化点
- 空值安全:在访问currentUser、teams、permissions前都做了类型检查,彻底避免forEach、includes等方法因调用对象为undefined而报错。
- 逻辑修正:用
some替代forEach,符合多团队权限场景的常见需求(用户只要在任意一个团队拥有所需权限即可访问)。 - 流程清晰:先校验登录状态,再检查权限,最后放行,逻辑顺序符合路由守卫的执行逻辑。
- 避免导航错误:每次调用
next()后用return终止后续逻辑,防止多次调用next()导致的导航冲突。
内容的提问来源于stack exchange,提问作者Mr. A
相关产品推荐
相关产品推荐

