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