关于vue-router:简单的vuerouter实现

6次阅读

共计 1737 个字符,预计需要花费 5 分钟才能阅读完成。

模仿 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 个层级的路由组件.

正文完
 0