vue-router使用复习
在vue脚手架中使用vue-router时,需要在main文件中使用下面的配置
1 2 3 4 5 6 7 8
| import Vue from 'vue' import App from './App.vue' import router from './router.js'
new Vue({ router, render: h => h(App) }).$mount('#app')
|
这段代码做了两件关键的事情
- 引入router,在引入时执行了router.js里的文件内容
- 在创建vue实例时传入了router的配置
然后我们看看router.js里的文件配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import Vue from 'vue'; import Router from './vue-router'; import Home from './views/Home'; import About from './views/About';
Vue.use(Router);
let router = new Router({ mode: 'hash', routes: [{ path: '/', component: Home }, { path: '/about', component: About, children: [{ path: 'a', component: { render:(h)=><h1>About Child A</h1> } }, { path: 'b', component: { render:(h)=><h1>About Child B</h1> } }] } ] })
export default router
|
这个文件关键的代码也有两处
- 调用了Vue.use,安装Router插件
- 调用了new Router创建一个Router配置对象并导出
在了解了这些后,我们正式开始实现一个vue-router
实现Router
从上面的使用方法我们可以看出,Router是一个类,而且提供了Router.install方法(Vue.use会调用这个方法)
用代码表现大致如下
1 2 3 4 5 6 7 8 9 10
| import install from './install'
class VueRouter { constructor(options : RouterOptions) {
} } VueRouter.install = install
export default VueRouter;
|
我们来看看install方法,install方法要进行一些数据的混合,还有一些初始化操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import {VueConstructor} from "vue";
export let _Vue : VueConstructor; import Link from './components/link'; import View from './components/view';
export default function install(Vue : VueConstructor | any, options : any){ _Vue = Vue; Vue.mixin({ beforeCreate(this : Vue | any) { if(this.$options.router){ this._routerRoot = this; this._router = this.$options.router; this._router.init(this); }else{ this._routerRoot = this.$parent && this.$parent._routerRoot; } } });
Vue.component('router-link',Link); Vue.component('router-view',View); }
|
然后控制权又回到了Router类里,Router需要根据当前的路径匹配对应的组件,还有根据不同的模式对路由进行处理,所以我们创建一个匹配器用于匹配路径,创建一个History对象对路由进行处理,因为hash模式和history模式,本质上都是监听事件进行跳转,所以我们可以抽出一个公共的父类处理共同的逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import HashHistory from './history/hash'; import BrowserHistory from './history/history'; import {History} from './history/base'; import createMatcher from './create-matcher';
class VueRouter {
matcher !: { addRoutes : Function, match : Function }; history !: History; static install : Function;
constructor(options : RouterOptions) { this.matcher = createMatcher(options.routes || []);
options.mode = options.mode || 'hash'; switch (options.mode) { case 'hash': this.history = new HashHistory(this); break; case 'history': this.history = new BrowserHistory(this); break; } this.beforeHooks = []; } }
|
看看匹配器的代码,比较简单,就是创建一个路由映射map,然后返回一个匹配的方法而已