vue-router做路由拦截时陷入死循环

今天分享一下使用vue-router做路由拦截时遇到的坑。

需要提前了解的api

1:router.beforeEach( to , from ,next) ;

  • to: Route: 即将要进入的目标 路由对象

  • from: Route: 当前导航正要离开的路由

  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

    • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

    • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

    • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

    • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

确保要调用 next 方法,否则钩子就不会被 resolved。

原因

我们一般在写拦截时会这样去写:

router.beforeEach((to, from, next) => {

  if(token) {
    next();
  }else {
    router.push({name:'login'})
  }

});
View Code

上诉的代码里的token ,是你需要存下的一个登录身份,这里可以存在store里或者是localStorage里,当然 也可以每次进行登录时 从后台获取。

这时 我们发现,不管我们在哪个页面拦截进入了死循环。其实这算是一个vue-router的一个机制了,当我们在router.push( {‘name’ : 'login'} ) 时又重新进入了我们当前的这个router-beforEach事件里,此时又进行了tokne的判断,还是没有token,导致又走到了router.push({name:'login'}) 里,然后就是一直死循环。

如何修改

如下:

router.beforeEach((to, from, next) => {
  
  if(Object.is(to.name,'login')) {
    next();
    return
  }
  
  if(token) {
    next();
  }else {
    router.push({name:'login'})
  }

});
View Code

这时 在第二次进入这个beforEach时,如果我们需要跳转到的页面是 login 页面,就直接next() 并且不再执行该函数。

总结

1:这个问题其实也是对 vue-router 的router.beforEach运行机制不了解导致

2:router.beforeEach ( ) 可以用来做前端的路由拦截,没有token时 就跳转到登录页。

3:对应的还有 router.afterEach 等api 可前往:Vue-router API 进行查看

原文地址:https://www.cnblogs.com/mamimi/p/9724824.html