vue-router源码浅显分析(一)--Vue.use(VueRouter), new VueRouter(options),HashHistory

本文深入探讨VueRouter的源码,详细分析了`Vue.use(VueRouter)`和`new VueRouter(options)`的过程,特别是HashHistory的工作原理。在VueRouter的install方法中,它扩展了Vue并添加了路由相关操作。在Vue实例的beforeCreate和destroyed钩子中,VueRouter执行了初始化。在new VueRouter时,根据routes和mode创建了History实例。在init方法中,依据History的类型调用了transitionTo方法,HashHistory会执行setupListeners来监听hash变化。文章还介绍了transitionTo、confirmTransition和路由组件的更新流程。
摘要由CSDN通过智能技术生成

1,vue中使用vueRouter需要通过vue.use(vueRouter),众所周知,这里实际上调用了VueRouter的install方法,对Vue进行了扩展,vueRouter的install方法如下:

function install (Vue) {
//如果已经挂载了,跳过
  if (install.installed && _Vue === Vue) { return }
//如果未挂载过, installed属性改为true
  install.installed = true;
//获取当前vue
  _Vue = Vue;

  var isDef = function (v) { return v !== undefined; };

  var registerInstance = function (vm, callVal) {
    var i = vm.$options._parentVnode;
    if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
      i(vm, callVal);
    }
  };
//在vue的beforeCreate钩子和destroyed钩子中新增关于路由的处理
  Vue.mixin({
    beforeCreate: function beforeCreate () {
      if (isDef(this.$options.router)) {
        this._routerRoot = this;
        this._router = this.$options.router; //new VueRouter()
        this._router.init(this); //如果Vue实例参数中,有指定的router属性,执行init初始化
//调用vue.util里的方法,通过get和set劫持this._route,router-view实时更新
        Vue.util.defineReactive(this, '_route', this._router.history.current);
      } else {
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
      }
      registerInstance(this, this);
    },
    destroyed: function destroyed () {
      registerInstance(this);
    }
  });
//给vue新增$router, $route属性,并指定get方法返回值,$route属性。于是就有了,this.$router和this.$route对象可以使用。
  Object.defineProperty(Vue.prototype, '$router', {
//this._routerRoot => this (即vue)
//this._router =>new VueRouter()
    get: function get () { return this._routerRoot._router } 
  });

  Object.defineProperty(Vue.prototype, '$route', {
    get: function get () { return this._routerRoot._route }
  });
//新增子组件RouterView, RouterLink
  Vue.component('RouterView', View);
  Vue.component('RouterLink', Link);

  var strats = Vue.config.optionMergeStrategies;
  // 默认一下组件内导航钩子跟created方法一样
  strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;
}

对于配置了路由的vue实例,install方法中做了如下两步操作:

1. this._router = this.$options.router; 获取VueRouter实例(传入的router:router 对象, router = new VueRouter({routes:[]}))

2. this._router.init(this) 重点, 执行VueRouter的init方法

---------------------------------------分割线-------------------------------------

第一步: new VueRouter({routes:[]})



var VueRouter = function VueRouter (options) {
  if ( options === void 0 ) options = {};

  this.app = null;
  this.apps = [];
  this.options = options;
  this.beforeHooks = [];
  this.resolveHooks = [];
  this.afterHooks = [];
//调用createRouteMap方法,遍历routes,执行addRouteRecord(递归)生成的record对象存入
//pathList pathMap nameMap。

//createRouteMap最后 return { pathList: pathList, pathMap: pathMap, nameMap: nameMap }
  this.matcher = createMatcher(options.routes || [], this);

  var mode = options.mode || 'hash';
//如果当前环境不支持history模式,强制切换到hash模式
  this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false;
  if (this.fallback) {
    mode = 'hash';
  }
//如果不是浏览器环境,切换到abstract模式
  if (!inBrowser) {
    mode = 'abstract';
  }
  this.mode = mode;
//根据mode值创建不同的实例,生成不同的history对象
  switch (mode) {
    case 'history':
      this.history = new HTML5History(this, options.base);
      break
    case 'hash':
      this.history = new HashHistory(this, options.bas
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值