起因
Vue 项目,在 router.js
中:
router.beforeEach((to, from, next) => {
NProgress.start();
if (!store.getters.logged) { // 未登录
store.dispatch("LOGIN").then(() => { // 登录并初始化
// 添加动态路由。 (dynamicRoutes 是已经经过权限筛选的动态路由)
router.addRoutes(dynamicRoutes);
try { // 这个 try 是为了 debug
next({...to}); // 重新跳转,即再次执行 router.beforeEach !!!!这儿出错了
} catch (e) {
console.log(e);
alert('error'); // 暂停
}
}).catch((msg) => { // 登录失败
console.log(msg); // 如果上面的 then 中没有用 try 捕获异常,会跳转到这儿
toLogin(); // 跳转登录
});
} else {
next();
}
});
上面的 next({...to})
抛出异常 (Chrome 控制台显示,Firefox 中不一样):
RangeError: Maximum call stack size exceeded
at RegExp.exec (<anonymous>)
at RegExp.[Symbol.match] (<anonymous>)
at String.match (<anonymous>)
at matchRoute (vue-router.esm.js?8c4f:1641)
at match (vue-router.esm.js?8c4f:1523)
at redirect (vue-router.esm.js?8c4f:1583)
at _createRoute (vue-router.esm.js?8c4f:1622)
at match (vue-router.esm.js?8c4f:1524)
at redirect (vue-router.esm.js?8c4f:1583)
at _createRoute (vue-router.esm.js?8c4f:1622)
解决
添加如下代码查看:
// .....
router.addRoutes(dynamicRoutes);
console.log('静态 routes ', router.options.routes);
console.log('静态及动态 routes (在 match.[[Scopes]] 里面可以看到) ', router.matcher);
显示已经成功添加了动态路由(当前请求的路由因为没有权限,没有添加进去)。
出错原因:
在动态路由里面最后添加了 个:
{
path: '*',
redirect: '/404' // 这个 route 一定要存在,否则会出现死循环(Chrome 中提示 )
}
然而路由表中却没有 /404
,所以导致了死循环。
解决方式:
添加 /404
路由。 或者,直接将 *
请求去掉,即没有找到请求时,会直接显示 App.vue
,一般是个空白页面。
上面 router.addRoutes(dynamicRoutes);
添加动态路由时,*
一定要放在 dynamicRoutes 数组的最后面,否则所有的动态路由都会跳转到 404。