今天分享一下使用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: true
、name: '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'}) } });
上诉的代码里的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'}) } });
这时 在第二次进入这个beforEach时,如果我们需要跳转到的页面是 login 页面,就直接next() 并且不再执行该函数。
总结
1:这个问题其实也是对 vue-router 的router.beforEach运行机制不了解导致
2:router.beforeEach ( ) 可以用来做前端的路由拦截,没有token时 就跳转到登录页。
3:对应的还有 router.afterEach 等api 可前往:Vue-router API 进行查看
所有评论(0)