Vue Router学习(十三)——全局导航守卫源码解析

前言

我们花了两节介绍了全局导航守卫、组件导航守卫的含义与用法。本节我们从源码的角度去解析一下导航守卫,加深对导航守卫的理解。

源码解析

全局导航守卫有三个,在github上打开源码,在router.ts文件就能找到三个全局守卫,首先我们就从守卫的初始化入手。

初始化

在router.ts中搜索beforeEach第一个结果就是beforeEach的ts类型,剩余两个就在其下面:

  • beforeEach,存在于接口Router类型中,具体的ts类型为:
  • beforeResolve的ts类型跟beforeEach是一样的,其中参数guard就是to,from,next:
  • afterEach的类型的参数跟前面有所不同,具体为to、from、failure:

三者的都会返回一个移除该钩子的函数,到此我们就知道三者的ts类型,继续搜索关键字会发现三者在实例化router中的初始值:

js 复制代码
beforeEach: beforeGuards.add,
beforeResolve: beforeResolveGuards.add,
afterEach: afterGuards.add,

三个守卫对应着三个guards,这三个guards是声明好的变量,对应的值也很简单就是将对应的ts类型用useCallbacks方法进行了创建:

js 复制代码
const beforeGuards = useCallbacks<NavigationGuardWithThis<undefined>>()
const beforeResolveGuards = useCallbacks<NavigationGuardWithThis<undefined>>()
const afterGuards = useCallbacks<NavigationHookAfter>()

在utils文件夹中我们可以找到callbacks文件里面就有useCallbacks方法:

该方法中有两个方法,一个add将参数添加到list中,并且返回当前值;一个reset将list清空,最后返回一个对象,其中list是通过slice 方法进行了拷贝。该方法主要用于收集导航守卫,在讲解导航守卫的时候我们也提到,可以有多个守卫。全局守卫的值就是add函数,全局守卫写法的根由就在此,我们将守卫函数当做参数调用beforeEach就能被收集到列表中:

js 复制代码
router.beforeEach((to, from) => {
})
// 也就是
useCallbacks.add((to, from) => {
})

执行

全局导航守卫是在导航时触发的,我们肯定需要找导航相关的逻辑,而导航方式有多种,这里我们以router.push方式为例解析,这里重点解析全局守卫相关代码。

  1. push方法会调用pushWithRedirect方法,该方法接收to参数。
  2. 导航过程有错误会通过createRouterError 创建错误,在返回结果中调用;无错误执行navigate 导航。
  3. 在navigate中会调用runGuardQueue ,在第一个.then中就能找到beforeEach: 我们可以看到上面函数return了runGuardQueue并且.then了下去,这里可以考虑下是何目的。
  4. 在runGuardQueue中会循环收集到的前置守卫,也就是beforeGuards.list(),然后执行guardToPromiseFn将结果添加到新数组guards中。
  5. 找到guardToPromiseFn,我们可以看到该函数声明三次也就是函数重载。
    该函数会返回一个Promise构造函数,在函数中会声明一个next函数 ,该函数会进行判断执行对应的导航流程。beforeEach中能够返回结果,这个结果就是通过next执行的。 6.beforResolve跟beforeEach逻辑基本一样,上面我们提到函数.then了下去,就是为了执行导航守卫流程
    7.回到pushWithRedirect方法中执行完navigate之后,继续往下走就是triggerAfterEach方法,用来执行afterEach:

afterGuards的list就是收集到的后置守卫,循环后置守卫然后执行runWithContext 函数,该函数主要为了兼容vue版本。

总结

以上就是导航守卫的源码解读,总结下来全局导航守卫执行过程就是收集、在导航过程中循环执行守卫钩子函数。

相关推荐
开发者小天15 分钟前
为什么 /deep/ 现在不推荐使用?
前端·javascript·node.js
如白驹过隙1 小时前
cloudflare缓存配置
前端·缓存
excel1 小时前
JavaScript 异步编程全解析:Promise、Async/Await 与进阶技巧
前端
Jerry说前后端1 小时前
Android 组件封装实践:从解耦到架构演进
android·前端·架构
步行cgn2 小时前
在 HTML 表单中,name 和 value 属性在 GET 和 POST 请求中的对应关系如下:
前端·hive·html
hrrrrb2 小时前
【Java Web 快速入门】十一、Spring Boot 原理
java·前端·spring boot
一枚小小程序员哈2 小时前
基于Vue的个人博客网站的设计与实现/基于node.js的博客系统的设计与实现#express框架、vscode
vue.js·node.js·express
找不到工作的菜鸟2 小时前
Three.js三大组件:场景(Scene)、相机(Camera)、渲染器(Renderer)
前端·javascript·html
定栓2 小时前
vue3入门-v-model、ref和reactive讲解
前端·javascript·vue.js
专注API从业者2 小时前
基于 Flink 的淘宝实时数据管道设计:商品详情流式处理与异构存储
大数据·前端·数据库·数据挖掘·flink