Vue 2出现Maximum call stack size exceeded问题求助
问题分析与修复:根据用户roles_id重定向时出现栈溢出错误
我在根据用户roles_id值重定向到对应路径时遇到问题,报错“Maximum call stack size exceeded”。使用switch语句尝试解决也无效,该问题在本地环境正常,但部署到服务器后出现。以下是我的代码:
const getUserRole = (to, from, next) => { const currentUser = JSON.parse(localStorage.getItem("userData")); if (currentUser) { if (currentUser.roles_id === 1 && to.name === "user-dashboard") { next({ name: "dashboard-new" }); } else if (currentUser.roles_id === 2 && to.name === "dashboard-new") { next({ name: "user-dashboard" }); } else if (currentUser.roles_id === 3 && to.name === "mails-track") { next({ name: "dispatch-dashboard" }); } else if (to.name === "dashboard-new" && currentUser.roles_id === 1) { next(); } else if (to.name === "user-dashboard" && currentUser.roles_id === 2) { next(); } else if (to.name === "dispatch-dashboard" && currentUser.roles_id === 3) { next(); } else { next("/"); } } else { next("/"); } }; export default [{ path: "/dashboard", name: "dashboard-new", component: () => import("@/views/dashboard/new/DashboardNew.vue"), meta: { requiresAuth: true }, beforeEnter: (to, from, next) => { const currentUser = JSON.parse(localStorage.getItem("userData")); if (currentUser && currentUser.roles_id === 1) { getUserRole(to, from, next); } else { next("/"); } } }, { path: "/user-dashboard", name: "user-dashboard", component: () => import("@/views/dashboard/new/user/UserDashboard.vue"), meta: { requiresAuth: true }, beforeEnter: (to, from, next) => { const currentUser = JSON.parse(localStorage.getItem("userData")); if (currentUser && currentUser.roles_id === 2) { getUserRole(to, from, next); } else { next("/"); } } } ];
核心问题:无限重定向循环
你的代码触发了无限重定向循环,这是栈溢出的根本原因:
- 当
roles_id=1的用户访问user-dashboard时,getUserRole会重定向到dashboard-new - 而
dashboard-new的beforeEnter钩子中,验证用户是roles_id=1后,又调用了getUserRole - 虽然
getUserRole中存在放行逻辑,但服务器环境下路由解析的严格性,加上重复调用守卫函数的行为,导致路由生命周期被反复触发,最终形成无限循环,耗尽调用栈
另外,代码存在冗余逻辑:路由钩子和getUserRole重复读取localStorage,且判断条件零散,容易出现逻辑漏洞。
修复方案:简化守卫逻辑,避免重复调用
优化思路
- 统一角色与路由的对应关系,避免零散的条件判断
- 移除路由钩子中的重复校验,用单一守卫函数处理所有角色路由的校验
- 明确逻辑分支:仅在用户访问非授权路由时重定向,否则直接放行
修复后的代码
// 统一的角色校验守卫 const checkUserRole = (to, from, next) => { const currentUser = JSON.parse(localStorage.getItem("userData")); if (!currentUser) { next("/"); return; } // 定义角色与专属路由的映射 const roleToRoute = { 1: "dashboard-new", 2: "user-dashboard", 3: "dispatch-dashboard" }; const allowedRouteName = roleToRoute[currentUser.roles_id]; // 访问的是自己的专属路由,直接放行 if (to.name === allowedRouteName) { next(); } // 访问了其他角色的专属路由,重定向到自己的路由 else if (Object.values(roleToRoute).includes(to.name)) { next({ name: allowedRouteName }); } // 其他未知路径,重定向到首页 else { next("/"); } }; export default [ { path: "/dashboard", name: "dashboard-new", component: () => import("@/views/dashboard/new/DashboardNew.vue"), meta: { requiresAuth: true }, beforeEnter: checkUserRole }, { path: "/user-dashboard", name: "user-dashboard", component: () => import("@/views/dashboard/new/user/UserDashboard.vue"), meta: { requiresAuth: true }, beforeEnter: checkUserRole } ];
额外说明
- 本地环境可能因缓存或路由匹配优先级问题,暂时未触发循环,但服务器环境的路由解析逻辑更严格,导致问题暴露
- 避免在路由守卫中嵌套调用守卫函数,每次
next()都会触发路由生命周期,极易引发循环
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

