06【手写vue-router】实现router-view

原理:根据路由取到要展示的组件,然后用render函数进行渲染。

myRouter.install = (Vue, options)=>{
    Vue.mixin({
        beforeCreate(){
            if(this.$options && this.$options.router){
                this.$router = this.$options.router;
                this.$route = this.$router.routeInfo;
            // 先渲染组件再执行onload事件,所以拿不到currentPath,所以用vue的响应式方法去观测路由的变化
                Vue.util.defineReactive(this, 'xxx', this.$router);
            }else{
                this.$router = this.$parent.$router;
                this.$route = this.$router.routeInfo;
            }
        }
    });
    /*
    只要外界使用了Vue-Router, 那么我们就必须提供两个自定义的组件给外界使用
    只要外界通过Vue.use注册了Vue-Router, 就代表外界使用了Vue-Router
    只要接通通过Vue.use注册了Vue-Router, 就会调用插件的install方法
    所以我们只需要在install方法中注册两个全局组件给外界使用即可
    * */
    Vue.component('router-link', {
        props: {
            to: String
        },
        render(){
            /*
            注意点: render方法中的this并不是当前实例对象, 而是一个代理对象
                    如果我们想拿到当前实例对象, 那么可以通过this._self获取
            * */
            // console.log(this._self.$router.mode);
            let path = this.to;
            if(this._self.$router.mode === 'hash'){
                path = '#' + path;
            }
            return {this.$slots.default}
        }
    });
    Vue.component('router-view', {
        render(h){
            // console.log('render');
            let routesMap = this._self.$router.routesMap;
            let currentPath = this._self.$route.currentPath;
            // console.log(currentPath);
            let currentComponent = routesMap[currentPath];
            return h(currentComponent);
        }
    });
}

你可能感兴趣的:(06【手写vue-router】实现router-view)