模仿vue-router实现简略的路由性能, 仿照vue-router应用的办法, 在router/index.js中配置路由文件从而逐渐实现目标.

  1. 实现繁难的PVueRouter类, 首先实现动态install办法, 保障 Vue.use(Router)这一步失常运行. 并挂载到组件中的$router属性

    let Vue // 定义Vue变量,在 install 办法中赋为真正的构造函数应用class PVueRouter {     constructor(options){        this.$options = options        // 为了不便,在此处将路由实例赋给Vue原型,这样在路由组件内能够通过 this.$router 拜访. 与上面的 mixin 同样作用        Vue.prototype.$router = this    }     // 静态方法 install    static install(_Vue){        Vue = _Vue        // 工作1:挂载$router  或者应用 mixin 在根组件混入以后路由实例        Vue.mixin({            beforeCreate() {            // 只有根组件领有router选项            if (this.$options.router) {                    // vm.$router                    Vue.prototype.$router = this.$options.router;                  }            }         });        Vue.component('router-link', RouterLink)        Vue.component('router-view', RouterView)        // 首先要定义 router-link 及 router-view 组件                  }}// import Router from 'pvue-router' // 引入简易版自定义的router类// Vue.use(Router)
  2. 此时运行会发现报错, 揭示还须要定义 router-linkrouter-view

    Vue.component('router-link', {         props: [ 'to' ],         // 无奈编译模板,须要应用render函数  <a href="#/about">router-link</a>  或者 jsx         // template: '<a>router-link</a>',         render(h) {             return h('a', {                 attrs: {                     href: '#' + this.to                 }             }, this.$slots.default)         },          })     Vue.component('router-view', {         render(h) {             return h(null)         }          })
  3. 定义current, 记录以后路由地址. 监听 hashchange 事件, 路由变动即时更新从而从新渲染 router-view 的内容.

    class PVueRouter { constructor(options){     this.$options = options     Vue.util.defineReactive(this, 'current', window.location.hash.slice(1) || '/')     window.addEventListener('hashchange', () => {         this.current = window.location.hash.slice(1) || '/'     })     this.routeMap = {}     this.$options.routes.forEach(route => {         this.routeMap[route.path] = route.component     });                   Vue.prototype.$router = this }Vue.component('router-view', {     render(h) {         const component = routeMap[current] || null;         return h(component);         }          })

至此实现了简略的路由性能, 然而当呈现嵌套路由时, 就会发现 Maximum call stack size exceeded. 因为外部又嵌套了router-view , 所以渲染路由对应的组件时会有限套娃......
比方以后路由地址为'/about/info', 对应AboutInfo组件; 其父级为 '/about', 对应About组件. 须要对其进行深度标记, 并应用 matched 代替 current 属性, 因为须要别离渲染2个层级的路由组件.