zoukankan      html  css  js  c++  java
  • vue-router 导航守卫

    前言

    Vue-Router导航守卫

    在本期文章中,我将为大家梳理弄明白以下几个事情:

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

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

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

    4:beforeEach是否可以叠加?

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

    正文

    1、transitionTo函数

    在之前说过的一个内容router实例的history属性帮助我们做了所有跳转部分的事情,所以导航守卫的内容也在history中。

    我们以HTML5History这个类来看一下这个push方法,

    push过程中调用了transitionTo完成了一系列的跳转内容,但这个方法在HTML5的类中并不存在,继承于base.js类中的方法。

    push:我们跳转时的$router.push就是这个方法。

    transitionTo就是实现路由跳转的方法:路由跳转。

    transitionTo的主流程是由confirmTranstion方法与uodateRoute方法结合起来的,翻译成普通话:路由跳转要先经过一个确认跳转的过程,在确认过程完成后进行一次路由的更新操作,

    1.1、confirmTransiton函数

    confirmTransiton做了什么呢?首先判断一下你是不是相同的路由。如果是那就什么都不做,第二步呢,我们要开始收集一波守卫了,然后把守卫收集起来,然后把每个守卫执行一遍,confirmTransition就算执行成功了。

    下面是部分源码截图:

    1.1.1、这个过程中的难点是什么?

    如何收集守卫组合成守卫队列?如何按顺序执行守卫的同时可以随时中止守卫队列?如何找到守卫队列执行完毕后的那个节点(守卫队列执行完可以通知一下)

    1.1.2、runQueue函数的思想

    在vue-router中封装了一个runQueue函数来解决上面的三个问题的后两个。第一个问题呢则涉及到vue-router处理路由的一个大篇章。所以这里我们先着重讲一下runQueue函数。

    迭代器模式来保证遍历队列时每一步都是可控的;队列完成后执行对应的回调函数,推断出函数参数的对应功能。

    接下来让我们看代码,代码之前先单拎出来几个变量:queue: 需要执行的守卫队列fn : 迭代器函数,守卫队列的每一个守卫都去执行迭代器函数

    fn的第二个参数使迭代器进入下一步,不掉用就不会进入下一步(很重点)

    cb: 结束时调用的回调函数

    runQueue是怎么帮助我们解决守卫队列处理的问题就算说完了。(快留起来,这函数简直吊极了!)

    处理守卫队列的大锤子我们已经制造好了,可以开工了,那你的守卫队列呢??

    对对对,还有守卫队列要收集。这个时候我们要想想有哪些守卫?

    1.1.3、守卫队列

    守卫有两大种类:前置守卫、后置守卫。

    前置守卫:

    1. 全局的前置守卫: beforeEach beforeResolve2. 路由独享的守卫: beforeEnter3. 组件内的守卫: beforeRouterEnter、beforeRouterUpdate、beforeRouteLeave后置守卫:1. 全局的后置守卫: afterEach

    我们要想一下这些守卫都是怎么注册的,

    在路由实例注册中:beforeEach、beforeResolve、afterEach在路由配置中注册的(路由独享守卫):beforeEnter组件内的路由守卫:beforeRouteLeave、beforeRouteUpdate、beforeRouteEnter

    好了我们要去榨取对应的守卫了,

    confirmTransition的守卫分为两个队列:我们先来看第一个队列

    一个queue的顺序:

    拿到被摧毁的组件的,榨取出所有组件内的离开守卫。全局的beforeEach组件。拿到更新的所有组件,榨取出所有组件内的更新守卫。遍历要进入的路由,拿到所有路由的独享守卫。加载要被激活的异步组件

    7个守卫中的4个守卫都在被按顺序拿出来了,放入第一个queue。

    再下一步要有一个处理守卫的迭代器:

    1.1.4、如何处理守卫

    我们该如何处理守卫?

    保证在守卫中可以停止并且跳转到其余路由,保证守卫可以正常通过,

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

    下面会有一点乱,请坐稳扶好:

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

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

    第二个queue:

    收集了被激活组件内的进入守卫全局的beforeResolve的守卫

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

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

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

    2、beforeEach

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

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

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

    总结

    我们来回答一下开篇的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守卫。最后完成路由的跳转。

  • 相关阅读:
    28 对10个数进行排序
    27 求100之内的素数
    26 请输入星期几的第一个字母,判断一下是星期几
    25 一个五位数,判断它是不是回文数
    24 给一个不多于5位的正整数
    23 请问第5个人多大?
    22 1+2!+3!+...+5!的和
    快捷生成getter和setter方法
    Error creating bean with name 'as' defined in class path resource
    CentOS7-1810 系统DNS服务器BIND软件配置说明
  • 原文地址:https://www.cnblogs.com/momo798/p/11907460.html
Copyright © 2011-2022 走看看