其实在路由护卫中,只有next()
是放行,其他的诸如:next('/logon') 、 next(to) 或许 next({ ...to, replace: true })
都不是放行,而是:中止当时导航,履行新的导航
能够这么理解:
next() 是放行,可是假如next()里有参数的话,next()就像被重载一样,就有了不同的功能。
而对于上面说的中止当时导航,履行新的导航打个比方:
现在我有一个护卫,在护卫中我运用next(‘/logon’),肯定有人认为是会直接跳转到/logon路由
beforeEach((to, from, next) => { next('/logon') }
其实履行要这么看:
beforeEach((to, from, next) => {
beforeEach(('/logon', from, next) => {
beforeEach(('/logon', from, next) => {
beforeEach(('/logon', from, next) => {
beforeEac... // 一向循环下去...... , 由于我们没有运用 next() 放行
}
}
}
把这个护卫改一下,当我在地址栏输入/home
时
beforeEach((to, from, next) => {
if(to.path === '/home') {
next('/logon')
} else {
// 假如要去的当地不是 /home , 就放行
next() }
}
所以想要拜访/home
能够这么看
beforeEach((to, from, next) => {
beforeEach(('/logon', from, next) => {
next() // 现在要去的当地不是 /home , 因而放行
}
}
要点就在这,next(‘/logon’)不是说直接去/logon路由,而是中止这一次路由护卫的操作,又进入一次路由护卫,就像嵌套一样,一层路由护卫,然后又是一层路由护卫,此刻路由护卫进入到第二层时,to.path现已不是/home了,这个时分才履行next()放行操作。
正认为如此许多人在运用动态增加路由addRoutes()
会遇到下面的状况:
在addRoutes()
之后第一次拜访被增加的路由会白屏,这是由于刚刚addRoutes()
就立刻拜访被增加的路由,但是此刻addRoutes()
没有履行结束,因而找不到刚刚被增加的路由导致白屏。因而需求从头拜访一次路由才行。
该怎么解决这个问题 ?
此刻就要运用next({ …to, replace: true })来保证addRoutes()时动态增加的路由现已被彻底加载上去。
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()方向出口。
代码应该是这样的
router.beforeEach((to, from, next) => {
const token = sessionStorage.getItem('access_token')
// 存在 token 阐明现已登录
if (token) {
// 登录过就不能拜访登录界面,需求中止这一次路由护卫,履行下一次路由护卫,并且下一次护卫的to是主页'
if (to.path === '/login') {
next({ path: '/' })
}
// 保存在store中路由不为空则放行 (假如履行了改写操作,则 store 里的路由为空,此刻需求从头增加路由)
if (store.getters.getRoutes.length || to.name != null) {
//放行
next()
} else {
// 将路由增加到 store 中,用来标记已增加动态路由
store.commit('ADD_ROUTER', '需求增加的路由')
router.addRoutes('需求增加的路由')
// 假如 addRoutes 并未完结,路由护卫会一层一层的履行履行,直到 addRoutes 完结,找到对应的路由
next({ ...to, replace: true })
}
} else {
// 未登录时,留意 :在这里也许你的项目不只有 logon 不需求登录 ,register 等其他不需求登录的页面也需求处理
if (to.path !== '/logon') {
next({ path: '/logon' })
} else {
next()
}
}