vue-router源码概览

源码这个东西对于实际的工作其实没有立竿见影的效果,不会像那些针对性极强的文章一样看了之后就立马可以运用到实际项目中,产生什么样的效果,源码的作用是一个潜移默化的过程,它的理念、设计模式、代码结构等看了之后可能不会立即知识变现(或者说变现很少),而是在日后的工作过程中悄无声息地发挥出来,你甚至都感觉不到这个过程

另外,优秀的源码案例,例如 vuereact这种,内容量比较庞大,根本不是三篇五篇十篇八篇文章就能说完的,而且写起来也很难写得清楚,也挺浪费时间的,而如果只是分析其中一个点,例如 vue的响应式,类似的文章也已经够多了,没必要再 repeat

所以我之前没专门写过源码分析的文章,只是自己看看,不过最近闲来无事看了 vue-router的源码,发现这种插件级别的东西,相比 vue这种框架级别的东西,逻辑简单清晰,没有那么多道道,代码量也不多,但是其中包含的理念等东西却很精炼,值得一写,当然,文如其名,只是概览,不会一行行代码分析过去,细节的东西还是要自己看看的

vue.use

vue插件必须通过 vue.use进行注册,vue.use的代码位于 vue源码的 src/core/global-api/use.js文件中,此方法的主要作用有两个:

  • 对注册的组件进行缓存,避免多次注册同一个插件
if (installedPlugins.indexOf(plugin) > -1) {
   
  return this
}
  • 调用插件的 install方法或者直接运行插件,以实现插件的 install
if (typeof plugin.install === 'function') {
   
  plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
   
  plugin.apply(null, args)
}

路由安装

vue-routerinstall方法位于 vue-router源码的src/install.js
主要是通过 vue.minxin混入 beforeCreatedestroyed钩子函数,并全局注册 router-viewrouter-link组件

// src/install.js
Vue.mixin({
   
  beforeCreate () {
   
    if (isDef(this.$options.router)) {
   
      this._routerRoot = this
      this._router = this.$options.router
      this._router.init(this)
      Vue.util.defineReactive(this, '_route', this._router.history.current)
    } else {
   
      this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
    }
    registerInstance(this, this)
  },
  destroyed () {
   
    registerInstance(this)
  }
})
...
// 全局注册 `router-view` 和 `router-link`组件
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)

路由模式

vue-router支持三种路由模式(mode):hashhistoryabstract,其中 abstract是在非浏览器环境下使用的路由模式,例如weex

路由内部会对外部指定传入的路由模式进行判断,例如当前环境是非浏览器环境,则无论传入何种mode,最后都会被强制指定为 abstract,如果判断当前环境不支持 HTML5 History,则最终会被降级为 hash模式

// src/index.js
let mode = options.mode || 'hash'
this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false
if (this.fallback) {
   
  mode = 'hash'
}
if (!inBrowser) {
   
  mode = 'abstract'
}

最后会对符合要求的 mode进行对应的初始化操作

// src/index.js
switch (mode) {
   
  case 'history':
    this.history = new HTML5History(this, options.base)
    break
  case 'hash':
    this.history = new HashHistory(this, options.base, this.fallback)
    break
  case 'abstract':
    this.history = new AbstractHistory(this, options.base)
    break
  default:
    if (process.env.NODE_ENV !== 'production') {
   
      assert(false, `invalid mode: ${
     mode}`)
    }
}

路由解析

通过递归的方式来解析嵌套路由

// src/create-route-map.js
function addRouteRecord 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值