JavaScript

超轻量级php框架startmvc

vue-router源码之history类的浅析

更新时间:2020-08-27 11:18:01 作者:startmvc
当前版本:3.0.3类目录:src/history/base.js前言:对于vue-router来说,有三种路由模式history,hash,abstrac

当前版本: 3.0.3

类目录: src/history/base.js

前言:

对于vue-router来说,有三种路由模式history,hash,abstract, abstract是运行在没有window的环境下的,这三种模式都是继承于history类,history实现了一些共用的方法,对于一开始看vue-router源码来说,可以从这里开始看起。

初始属性


router: Router; 表示VueRouter实例。实例化History类时的第一个参数
 base: string; 表示基路径。会用normalizeBase进行规范化。实例化History类时的第二个参数。
 current: Route; 表示当前路由(route)。
 pending: ?Route; 描述阻塞状态。
 cb: (r: Route) => void; 监听时的回调函数。
 ready: boolean; 描述就绪状态。
 readyCbs: Array<Function>; 就绪状态的回调数组。
 readyErrorCbs: Array<Function>; 就绪时产生错误的回调数组。
 errorCbs: Array<Function>; 错误的回调数组

 // implemented by sub-classes
 <!-- 下面几个是需要子类实现的方法,这里就先不说了,之后写其他类实现的时候分析 -->
 +go: (n: number) => void;
 +push: (loc: RawLocation) => void;
 +replace: (loc: RawLocation) => void;
 +ensureURL: (push?: boolean) => void;
 +getCurrentLocation: () => string;

对于history类来说,主要是下下面两个函数的逻辑

transitionTo

这个方法主要是对路由跳转的封装, location接收的是HTML5History,HashHistory,AbstractHistory, onComplete是成功的回调,onAbort是失败的回调


transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) {
 const route = this.router.match(location, this.current) // 解析成每一个location需要的route
 this.confirmTransition(route, () => {
 this.updateRoute(route)
 onComplete && onComplete(route)
 this.ensureURL()

 // fire ready cbs once
 if (!this.ready) {
 this.ready = true
 this.readyCbs.forEach(cb => { cb(route) })
 }
 }, err => {
 if (onAbort) {
 onAbort(err)
 }
 if (err && !this.ready) {
 this.ready = true
 this.readyErrorCbs.forEach(cb => { cb(err) })
 }
 })
 }

confirmTransition

这是方法是确认跳转,route是匹配的路由对象, onComplete是匹配成功的回调, 是匹配失败的回调


confirmTransition(route: Route, onComplete: Function, onAbort?: Function) {
 const current = this.current
 const abort = err => { // 异常处理函数
 if (isError(err)) {
 if (this.errorCbs.length) {
 this.errorCbs.forEach(cb => { cb(err) })
 } else {
 warn(false, 'uncaught error during route navigation:')
 console.error(err)
 }
 }
 onAbort && onAbort(err)
 }
 if (
 isSameRoute(route, current) &&
 // in the case the route map has been dynamically appended to
 route.matched.length === current.matched.length
 ) {
 this.ensureURL()
 return abort()
 }
 <!-- 根据当前路由对象和匹配的路由:返回更新的路由、激活的路由、停用的路由 -->
 const {
 updated,
 deactivated,
 activated
 } = resolveQueue(this.current.matched, route.matched)
 <!-- 需要执行的任务队列 -->
 const queue: Array<?NavigationGuard> = [].concat(
 // beforeRouteLeave 钩子函数
 extractLeaveGuards(deactivated),
 // 全局的beforeHooks勾子
 this.router.beforeHooks,
 // beforeRouteUpdate 钩子函数调用
 extractUpdateHooks(updated),
 // config里的勾子
 activated.map(m => m.beforeEnter),
 // async components
 resolveAsyncComponents(activated)
 )
 
 this.pending = route
 <!-- 对于queue数组所执行的迭代器方法 -->
 const iterator = (hook: NavigationGuard, next) => {
 if (this.pending !== route) {
 return abort()
 }
 try {
 hook(route, current, (to: any) => {
 if (to === false || isError(to)) {
 // next(false) -> abort navigation, ensure current URL
 this.ensureURL(true)
 abort(to)
 } else if (
 typeof to === 'string' ||
 (typeof to === 'object' && (
 typeof to.path === 'string' ||
 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)
 }
 }
 
 runQueue(queue, iterator, () => {
 const postEnterCbs = []
 const isValid = () => this.current === route
 <!-- beforeRouteEnter 钩子函数调用 -->
 const enterGuards = extractEnterGuards(activated, postEnterCbs, isValid)
 const queue = enterGuards.concat(this.router.resolveHooks)
 <!-- 迭代运行queue -->
 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() })
 })
 }
 })
 })
 }

结语:

每一次总结,都是对之前读源码的再一次深入的了解

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

vue-router history类