美文网首页
Vue vue-router简单实现

Vue vue-router简单实现

作者: 爱吃馒头不吃辣 | 来源:发表于2021-01-06 00:17 被阅读0次
    // 1.创建VueRouter类
    let Vue
    class VueRouter {
        constructor(options) {
            // 6.存储路由配置信息
            this.$opt = options;
            // 18.存储当前路由
            this.current = window.location.hash.slice(1) || '/';
            // 19.新建响应式属性matched,记录路由映射关系
            Vue.util.defineReactive(this, 'matched', []);
            // 20.match方法可以递归遍历路由表,获取匹配关系
            this.match();
            // 24.监听路由变化
            window.addEventListener('hashchange', () => {
                this.current = window.location.hash.slice(1) || '/';
                // 25.每次路由变化映射表指控重新获取
                this.matched = [];
                this.match();
            })
        }
        match(routers) {
            routers = routers || this.$opt.routes;
            // 21.遍历路由将当前路由存储到matched映射关系数组中
            for (const route of routers) {
                // 22.如果当前是根目录直接存入映射关系中
                if (route.path === '/' && this.current === '/') {
                    this.matched.push(route);
                    return;
                }
                // 23.非根目录情况下,获取其嵌套路由。递归存入
                if (route.path !== '/' && this.current.indexOf(route.path) != -1) {
                    this.matched.push(route)
                    if (route.children) {
                        this.match(route.children)
                    }
                    return;
                }
            }
        }
    
    }
    
    // 3.实现install插件方法,install真正的执行者是Vue.use(VueRouter),所以此处的形参_Vue就是Vue的构造函数
    VueRouter.install = function (_Vue) {
        Vue = _Vue
        // 4.在Vue原型挂载$router,使用mixin延迟到组件构建之后执行不然获取不到this.$options
        Vue.mixin({
            beforeCreate() {
                // 5.只有在this.$options.router存在时赋值给$router,因为在生命周期内,this指的是Vue组件实例
                if (this.$options.router) {
                    Vue.prototype.$router = this.$options.router
                }
            },
        })
        // 7.实现router-link
        Vue.component('router-link', {
            props: {
                to: {
                    type: String,
                    required: true
                },
            },
            // 8.router-link的本质其实就是<a href='#/about'></a>
            render(h) {
                // 9.这里的this指的是router-link组件实例
                return h('a', {
                    attrs: {
                        href: `#${this.to}`
                    }
                }, this.$slots.default);
            },
        })
    
        // 10.实现router-view,本质就是将路由匹配的component加载出来
        Vue.component('router-view', {
            // 11.涉及到嵌套路由
            render(h) {
                // 12.标记当前router-view的深度,标记自己是个routerView
                this.$vnode.data.routerView = true;
                // 13.记录深度
                let depth = 0;
                // 14.获取父元素
                let parent = this.$parent;
    
                // 15.判断是不是routerView,不停循环向上去找
                while (parent) {
                    // 16.需要从$vnode.data中获取routerView,先判断是否存在
                    const vnodeData = parent.$vnode && parent.$vnode.data
                    if (vnodeData) {
                        if (vnodeData.routerView) {
                            // 17.所有条件都满足,说明parent是一个router-view
                            depth++
                        }
                    }
                    // 16.赋值新的父元素
                    parent = parent.$parent
                }
                let component = null;
                // 24.根据深度获取路由信息
                let router = this.$router.matched[depth];
                if (router) {
                    component = router.component
                }
                return h(component)
            },
        })
    }
    
    // 2.导出VueRouter
    export default VueRouter
    

    相关文章

      网友评论

          本文标题:Vue vue-router简单实现

          本文链接:https://www.haomeiwen.com/subject/xlvgoktx.html