争怎路由网:是一个主要分享无线路由器安装设置经验的网站,汇总WiFi常见问题的解决方法。

带你完全搞定vue-Router的导航守卫

时间:2024/5/30作者:未知来源:争怎路由网人气:

typeof to.name === 'string' )) ) { // next('/') or next({ path: '/' }) -> redirect abort() // 我们就执行路由跳转操作,并且守卫队列停止下面的迭代 if (typeof to === 'object' && to.replace) { this.replace(to) } else { this.push(to) } } else { // confirm transition and pass on the value // 接续迭代下去咯 next(to) } }) } catch (e) { abort(e) } }

next函数,之前在将runQueue的函数的时候,fn接收第二个参数(之前画过重点),第二个参数的回调函数是完成迭代器向下一步执行的功能。

下面会有一点乱:

所有的前置守卫都接收三个参数

beforeEnter(to,from,next)=>{
    //这个next就是我们看到的 hook里面接收的箭头函数((to:any)=>{})
    //这个箭头函数里面对迭代器的next进行了一下掉用,
    //保证在一定情况下迭代器可以向下走一步。
    next('/index')
    // 我们在这种next('/index')传递一个可以执行的路径时,(to:any)=>{}
    //这个箭头函数并不会调用迭代的next,而是跳转别的路径执行了push操作。
    // 如果我们不掉用守卫中的next,迭代器的next肯定并不会执行,守卫的迭代就停止了,
    // 守卫堵塞confirmTransition并不会执行完毕,也就不会由后面的更细路由操作了。
}
runQueue(queue, iterator, () => {
      const postEnterCbs = []
      const isValid = () => this.current === route
      // wait until async components are resolved before
      // extracting in-component enter guards
      const enterGuards = extractEnterGuards(activated, postEnterCbs, isValid)
      const queue = enterGuards.concat(this.router.resolveHooks)
      runQueue(queue, iterator, () => {
        if (this.pending !== route) {
          return abort()
        }
        this.pending = null
        onComplete(route)
        if (this.router.app) {
          this.router.app.$nextTick(() => {
            postEnterCbs.forEach(cb => { cb() })
          })
        }
      })
    })

我们在把第一个queue(四个守卫与一个异步组件的加载)执行完毕后,要收集与执行第二个queue了,

第二个queue:

  1. 收集了被的激活组件内的进入守卫

  2. 全局的beforeResolve的守卫

收集完开始执行第二个queue的迭代。第二个queue执行完执行一下onComplete函数,代表着confirmTransition方法执行完毕了。确认路由的过程结束了,

下面就是updateRoute的过程。updateRoute的时候执行全部的后置守卫,因为更新路由之后,当前的路由已经变化了,所以在给守卫传参数的时候缓存了一下,之前的路由。

updateRoute (route: Route) {
    const prev = this.current
    this.current = route
    this.cb && this.cb(route)
    this.router.afterHooks.forEach(hook => {
      hook && hook(route, prev)
    })
  }

所以为什么afterEach没有next呢?因为afterEach根本不在迭代器之内,他就没有next来触发迭代器的下一步。

最后我们说一下beforeEach的内容:
我们设置beforeEach全局守卫的时候,守卫们存储在哪里?

beforeEach (fn: Function): Function {
    return registerHook(this.beforeHooks, fn)
}
function registerHook (list: Array<any>, fn: Function): Function {
  list.push(fn)
  // 返回值是一个function
  return () => {
    const i = list.indexOf(fn)
    if (i > -1) list.splice(i, 1)
  }
}

这段代码beforeEach是通过注册守卫的方式,将注册的全局前置守卫放在beforeHooks的容器内,这个容器里面装载着所有的前置守卫

1661f0d037728a31.png

一家人(全局的 前置进入、前置resolve、后置守卫)整整齐齐的放在对应的容器里面,容器是个数组,所以注册全局守卫的时候,是支持注册多个的,

router.beforeEach(()=>{xxx});
router.beforeEach(()=>{yyy});
// 这两个守卫都会执行,只是先注册的先执行,
// registerHook这个方法还可以清除对应的守卫,这个方法也可以使用

总结

我们来回答一下开篇的5个问题

1:导航守卫的执行顺序是怎么样的?

beforeRouteLeave < beforeEach < beforeRouteUpdate < beforeEnter < beforeRouteEnter < beforeResolve < afterEach

2:导航守卫中的next的用处?

next的作用,使导航守卫队列的继续向下迭代

3:为什么afterEach守卫没有next?

afterEach根本不在导航守卫队列内,没有迭代的next

4:beforeEach是否可以叠加?

beforeEach是可以叠加的,所有的全局前置守卫按顺序存放在beforeHooks的数组里面,

5:路由跳转经历了哪几部分?

路由跳转的核心方法是transitionTo,在跳转过程中经历了一次confirmTransition,

(beforeRouteLeave < beforeEach < beforeRouteUpdate < beforeEnter < 异步组件加载)这样顺序的queue为第一个,

在第一个queue迭代完毕后,执行第二个(beforeRouteEnter < beforeResolve)这样顺序的queue,

在执行完毕后,开始执行updateRoute,之后执行全局的afterEach守卫。最后完成路由的跳转。

5个问题解答完毕,希望对你的业务有帮助。

以上就是带你彻底搞定vue-Router的导航守卫的详细内容,更多请关注php中文网其它相关文章!


网站建设是一个广义的术语,涵盖了许多不同的技能和学科中所使用的生产和维护的网站。



关键词:带你完全搞定vue-Router的导航守卫




Copyright © 2012-2018 争怎路由网(http://www.zhengzen.com) .All Rights Reserved 网站地图 友情链接

免责声明:本站资源均来自互联网收集 如有侵犯到您利益的地方请及时联系管理删除,敬请见谅!

QQ:1006262270   邮箱:kfyvi376850063@126.com   手机版