其实在路由护卫中,只有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()
   }
 }