Appearance
Vue-router
一、简介
- VueRouter 是一个构造函数,有三种实现方式:hash、history、abstract
- 特点对比:
- hash 特点丑 兼容性好 location.hash = 'xx' / window.addEventListener('hashchange')
- history 漂亮像正常路径一样,但是需要服务端支持 history-fallback pushState / window。addEventListener('popstate')
- 前端路由的核心:根据路径,去渲染对应的组件
二、install原理
js
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
});
new Vue({
router, // 创建实例时提供router属性 表示初始化路由
render: h => h(App),
}).$mount('#app')
// 1. 初始化调用Vue.use注入路由构造函数的时候,会默认调用Vue.install方法
Vue.use(VueRouter,{});
// 源码
Vue.use = function (plugin, options) {
// this为大Vue构造函数
plugin.install(this, options)
}
// 2. VueRouter的类上挂载一个install方法
export default class VueRouter{
}
VueRouter.install = install;
// 3. install作用:
// a.存储Vue实例到全局变量中
// b.调用Vue.mixin方法,在beforeCreate的声明周期钩子中混入router实例
// c.调用vuerouter的init方法进行初始化
export let _Vue;
export function install(Vue, options) {
_Vue = Vue;
Vue.mixin({
beforeCreate() { // 每个组件都会执行beforecreate方法
// 获取到每个人的实例,给实例添加属性
if (this.$options.router) {
this._routerRoot = this; // 把根实例挂在到_routerRoot上
this._router = this.$options.router;
// this._router 路由的实例 new VueRouter
this._router.init(this);
// global-api 里面定义了这个方法
Vue.util.defineReactive(this, '_route', this._router.history.current)
} else {
// this._routerRoot指向了当前 根组件的实例
// iifecycleMixin 构建父子关系
this._routerRoot = this.$parent && this.$parent._routerRoot
// this._routerRoot._router
}
}
// 根_routerRoot => 父亲_routerRoot => 儿子_routerRoot => 孙子_routerRoot
});
Object.defineProperty(Vue.prototype,'$route',{
get(){
return this._routerRoot._route // current 对象里面放的都是属性 path matched
}
});
Object.defineProperty(Vue.prototype,'$router',{
get(){
// router.history.push()
return this._routerRoot._router; // addRoute match
}
});
Vue.component('router-link',RouterLink);
Vue.component('router-view',RouterView)
}