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,然后返回一个匹配的方法而已