起因

Vue 项目,在 router.js 中:

  1. router.beforeEach((to, from, next) => {
  2. NProgress.start();
  3. if (!store.getters.logged) { // 未登录
  4. store.dispatch("LOGIN").then(() => { // 登录并初始化
  5. // 添加动态路由。 (dynamicRoutes 是已经经过权限筛选的动态路由)
  6. router.addRoutes(dynamicRoutes);
  7. try { // 这个 try 是为了 debug
  8. next({...to}); // 重新跳转,即再次执行 router.beforeEach !!!!这儿出错了
  9. } catch (e) {
  10. console.log(e);
  11. alert('error'); // 暂停
  12. }
  13. }).catch((msg) => { // 登录失败
  14. console.log(msg); // 如果上面的 then 中没有用 try 捕获异常,会跳转到这儿
  15. toLogin(); // 跳转登录
  16. });
  17. } else {
  18. next();
  19. }
  20. });

上面的 next({...to}) 抛出异常 (Chrome 控制台显示,Firefox 中不一样):

  1. RangeError: Maximum call stack size exceeded
  2. at RegExp.exec (<anonymous>)
  3. at RegExp.[Symbol.match] (<anonymous>)
  4. at String.match (<anonymous>)
  5. at matchRoute (vue-router.esm.js?8c4f:1641)
  6. at match (vue-router.esm.js?8c4f:1523)
  7. at redirect (vue-router.esm.js?8c4f:1583)
  8. at _createRoute (vue-router.esm.js?8c4f:1622)
  9. at match (vue-router.esm.js?8c4f:1524)
  10. at redirect (vue-router.esm.js?8c4f:1583)
  11. at _createRoute (vue-router.esm.js?8c4f:1622)

解决

添加如下代码查看:

  1. // .....
  2. router.addRoutes(dynamicRoutes);
  3. console.log('静态 routes ', router.options.routes);
  4. console.log('静态及动态 routes (在 match.[[Scopes]] 里面可以看到) ', router.matcher);

显示已经成功添加了动态路由(当前请求的路由因为没有权限,没有添加进去)。

出错原因:
在动态路由里面最后添加了 个:

  1. {
  2. path: '*',
  3. redirect: '/404' // 这个 route 一定要存在,否则会出现死循环(Chrome 中提示 )
  4. }

然而路由表中却没有 /404 ,所以导致了死循环。
解决方式:
添加 /404 路由。 或者,直接将 * 请求去掉,即没有找到请求时,会直接显示 App.vue ,一般是个空白页面。

上面 router.addRoutes(dynamicRoutes); 添加动态路由时,* 一定要放在 dynamicRoutes 数组的最后面,否则所有的动态路由都会跳转到 404。