栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

vue-router源码之history类的浅析

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

vue-router源码之history类的浅析

当前版本: 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; 就绪状态的回调数组。
 readyErrorCbs: Array; 就绪时产生错误的回调数组。
 errorCbs: Array; 错误的回调数组

 // 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) })
   }
  })
 }

/confirm/iTransition

这是方法是确认跳转,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 = [].concat(
      // beforeRouteLeave 钩子函数
      extractLeaveGuards(deactivated),
      // 全局的beforeHooks勾子
      this.router.beforeHooks,
      // beforeRouteUpdate 钩子函数调用
      extractUpdateHooks(updated),
      // config里的勾子
      activated.map(m => m.beforeEnter),
      // async components
      resolveAsyncComponents(activated)
    )
    
    this.pending = route
    
    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
      
      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() })
   })
 }
      })
    })
  }

结语:

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/75625.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号