vue原理分析(五)--使用VueRouter
今天我们来分析使用VueRouter
VueRouter的使用分为以下几步
1. 引入VueRouter的js文件
2. 创建路由实例
3. 配置路由
4. 将路由实例挂载到vue实例
5. 使用路由
1. 引入VueRouter的js文件
import VueRouter from 'vue-router'
Vue.use(VueRouter)
第一句是引入VueRouter的js文件
VueRouter 是从 'vue-router' 模块中导出的核心类,它提供了创建路由实例以及相关路由管理的方法
第二句是 在Vue里面注册VueRouter插件,VueRouter本质是一个插件
Vue.use() 是 Vue.js 提供的一个全局API,用于安装 Vue 插件
1.1 研究下Vue.use()
Vue.use = function (plugin) {
// 一. 定义一个数组 如果this._installedPlugins不存在,就执行this._installedPlugins = []
const installedPlugins = this._installedPlugins || (this._installedPlugins = []);
// 二. 单例设计模式,判断是否注册,已经注册直接return
if (installedPlugins.indexOf(plugin) > -1) {
return this;
}
// additional parameters
// 三. 获取其他参数,如 Vue.use(plugin,a,b)
const args = toArray(arguments, 1);
// 四. 在args数组第一项添加Vue实例
args.unshift(this);
// 五. 如果plugin是对象,且有install方法,则执行install,并把参数传入,如果plugin本身是函数,则执行plugin
if (isFunction(plugin.install)) {
plugin.install.apply(plugin, args);
}
else if (isFunction(plugin)) {
plugin.apply(null, args);
}
// 六.将plugin存储到数组中,记录是否已经注册
installedPlugins.push(plugin);
return this;
};
1.2 研究下Vue.use(VueRouter)
// 一. VueRouter对象中有install函数
function install (Vue) {
// 二. 判断是否已经install,已经install则直接返回
if (install.installed && _Vue === Vue) { return }
install.installed = true;
_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.mixin({
// 四. 添加全局的 beforeCreate、destroyed 生命周期方法
beforeCreate: function beforeCreate () {
// 五. 调用了 VueRouter 实例的 init 方法进行初始化
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: function destroyed () {
registerInstance(this);
}
});
// 六. 将$router和route挂载到Vue原型
Object.defineProperty(Vue.prototype, '$router', {
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);
// 八. 添加新的生命周期 beforeRouteEnter、beforeRouteLeave、beforeRouteUpdate
var strats = Vue.config.optionMergeStrategies;
// use the same hook merging strategy for route hooks
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;
}
2. 配置路由
const routes = []
3. 创建路由实例
const routes = []
const router = new VueRouter({
routes
})
4. 将路由实例挂载到vue实例
看入口文件main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
本质上
new Vue({
el: '#app',
router:router, // 注入到根实例中
render: h => h(App)
})
意思就是
导入路由实例
创建Vue实例的时候,将路由实例挂载到Vue根实例上
5. 使用路由
用install中注册的全局组件
<router-view></router-view>
<router-link to="/detail">去详情页</router-link>