vue-router使用next()跳转到指定路径时会无限循环问题
作者:web_blog
解释1
beforeRouteLeave (to, from, next) { console.log('离开路路由') if(to.fullPath==='/home'){ next(); }else{ next('/home') }
这个是组件路由,我想实现的效果是在这个页面点击浏览器的返回按钮后要返回 /home页面而不是上一个页面,上面的代码是没问题的,而我之前的写法就一直死循环
// 下面的写法会死循环 beforeRouteLeave (to, from, next) { console.log('离开路路由') next('/home') }
vue-router的next()方法无参和有参时是不一样的
当执行钩子函数时如果遇到next(’/home’)等时会中断当前导航,
比如当前导航是去/a,那么遇到next(’/home’)后就会把to.path改为/home,然后会重新触发这个离开的钩子,
注意:此时会重新触发执行这个钩子,而不是在这个钩子函数继续执行的
当重新触发后就会继续执行next(’/home’)所以会一直循环。
至于解决办法就是判断下,如果已经是/home了就next()。
解释2
为什么next()指定路径会出现死循环
router.beforeEach((to, from, next) => { console.log('beforeEach'); if(true){ next('/'); }else{ next(); } });
next()直接跳转到to.path路径,没有再执行一遍beforeEach导航钩子,next(’/’)或者next(’/login’)自己指定路径的,路由跳转的时候还执行一遍beforeEach导航钩子,所以上面出现死循环;
栗子:
如我们登录页(’/login’)面进入首页(’/’),可以这么写:
router.beforeEach((to, from, next) => { var userInfo= JSON. parse(sess ionStorage. getItem('userInfoStorage'));//获取浏览器缓存的用户信息 if(userInfo){//如果有就直接到首页咯 next() ; }else{ if(to. path==' /login' ){//如果是登录页面路径,就直接next() next() ; }else{//不然就跳转到登录; next(' /login'); } } });
问题
出现无限循环是因为之前我没有弄清楚next()流程
因为每次跳转到一个路由的时候都会 触发 全局守卫 由于判断条件未改变 所以 一直循环
解决方法
判断to路由的meta (isRequireAuthTrue)是否为true
判断是否登陆(isLogin)
// ('/')为登陆界面 // next() 默认跳转to的path if(isRequireAuthTrue){ if(isLogin){ console.log('导航守卫保护'); next(); //成功则跳转 }else { console.log('你还没有登陆!'); next({path:'/'}) //失败则跳转到登陆页面 } }else { next();//不需要导航守卫的则直接next跳转 }
解释3
问题描述
在调用Vue中的全局前置导航守卫beforeEach(to, from, next)中的next函数,在给next()传参数的时候出现死循环的问题!
导致问题原因
其实导致这个问题的根本是没有完全理解beforeEach()和next("/somewhere")的作用首先,我们来看看next()的用法
究其根本是当执行了next("/somewhere")的时候又触发了beforeEach()这个钩子,所以就变成了无限死循环!
解决办法
router.beforeEach((to, from, next) => { let {path} = to; if(path=== "/somewhere") { next(); // 导航目的地符合预期,继续后续事情 }else { next("/somewhere"); // 导航目的地不符合预期,重新路由新路径地址,然后会再次触发beforeEach钩子并进行二次判断 } });
解释4
页面跳墙中使用 vue-router
中的 beforeEach
的死循环问题
问题展现
import Router from 'vue-router' const router = new Router({ {path: '/', component: index }, {path: '/login', component: login}, {path: '/error', component: error}, {path: '*', component: error} }) router.beforeEach((to, from, next) => { const isLogin = sessionStorage.getItem('loginData') if (isLogin) { next() } else { next('/error') } })
最近在使用时,一直陷入死循环,当时的想法是如何将路由提取出来,脱离beforeEach的控制,之后发现不可行。
上面问题再现,会出现死循环,因为 /error 会在进入前 又要进入beforeEach中 ,这样就会一直循环下去
所以就是想如何跳出这个循环即可
router.beforeEach((to, from, next) => { const isLogin = sessionStorage.getItem('loginData') if (isLogin) { next() } else { //next('/error') if (to.path === '/error') { //这就是跳出循环的关键 next() } else { next('/error') } } })
这样写,其实这个会执行两次,第二次进来是以/error的路由进来的
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。