📦 VUE路由守卫中的next
1. 路由守卫
1 | /** |
但是在看别的项目时常常能看到next('/login')
、 next(to)
、next(false)
或者 next({ ...to, replace: true })
这又是啥意思呢??
其实在路由守卫中,只有
next()
是放行,其他的诸如:next('/login')
、next(to)
、next(false)
或者next({ ...to, replace: true })
都不是放行,而是:中断当前导航,执行新的导航
中断当前导航:VUE中的中断就是此时不会执行
router.afterEach(() => {}
,不会执行后面的钩子函数
2. next函数
举个栗子:
现在我有一个守卫,在守卫中我使用next('/login')
,肯定有同学认为是会直接跳转到/login
路由:
1 | beforeEach((to, from, next) => { |
然而年轻人不讲武德,执行时需要这么看:
1 | // 伪代码 |
这样就会导致死循环,在换一个我们一起看一下:
1 | beforeEach((to, from, next) => { |
当我们在地址栏中输入/home
的时候,第一次执行了beforeEach((to, from, next)
,但是这个路由守卫中判断了如果要去的地方是'/home'
,就执行next('/login')
,所以这个守卫的真正执行,应该如下:
1 | // 伪代码 |
注意:重点就在这,next('/login')
不是说直接去/login
路由,而是中断这一次路由守卫的操作,又进入一次路由守卫,就像嵌套一样,一层路由守卫,然后又是一层路由守卫,此时路由守卫进入到第二层时,to.path
已经不是/home
了,这个时候才执行next()
放行操作。
3. 动态路由
很多人在使用动态添加路由addRoutes()
会遇到下面的情况:
在addRoutes()
之后第一次访问被添加的路由会白屏,这是因为刚刚addRoutes()
就立刻访问被添加的路由,然而此时addRoutes()
没有执行结束,因而找不到刚刚被添加的路由导致白屏。因此需要重新访问一次路由才行。
此时就要使用next({ ...to, replace: true })
来确保addRoutes()
时动态添加的路由已经被完全加载上去。
3.1 next({ …to, replace: true })
next({ ...to, replace: true })
中的replace: true
只是一个设置信息,告诉VUE本次操作后,不能通过浏览器后退按钮,返回前一个路由。因此next({ ...to, replace: true })
可以写成next({ ...to })
,不过你应该不希望用户在addRoutes()
还没有完成的时候,可以点击浏览器回退按钮搞事情吧。
其实next({ ...to })
的执行很简单,它会判断:
如果参数to不能找到对应的路由的话,就再执行一次beforeEach((to, from, next)
直到其中的next({ ...to})
能找到对应的路由为止。也就是说此时addRoutes()
已经完成啦,找到对应的路由之后,接下来将执行前往对应路由的beforeEach((to, from, next)
,因此需要用代码来判断这一次是否就是前往对应路由的beforeEach((to, from, next)
,如果是,就执行next()
放行。
如果守卫中没有正确的放行出口的话,会一直next({ ...to})
进入死循环 !!! 因此你还需要确保在当addRoutes()
已经完成时,所执行到的这一次beforeEach((to, from, next)
中有一个正确的next()
方向出口。
1 | router.beforeEach((to, from, next) => { |