封装vue-router,实现基础功能

封装vue-router源码


class VueRouter{
    constructor(options){
        const {routes}=options;
        // 监听当前页面的hash值的切换
        // 当第一次解析页面时,会有一个默认的hash值
        /// 循环遍历routes,把path和component重新放入一个新的对象中
        // {"/home/:id":home}
        this.routeMap = routes.reduce((prev,next)=>{
            prev[next.path]=next.component;
            return prev;
        },{});
        // 
        // this ==> VueRouter的实例,也是每一个组件上的_router
        Vue.util.defineReactive(this.route={},'path',"/");
        window.addEventListener("load",()=>{
            // 如果没有hash值,那么给其赋默认值/;如果本来就有hash,什么也不做;
            location.hash?null:location.hash="/";
        })
        window.addEventListener("hashchange",()=>{
            // 当页面hash值发生改变以后,会触发这个方法;1.a标签  2.手动
            // 获取当当前页面的hash值,获取到#后面的字符串;
            let path = location.hash.slice(1);
            this.route.path = path;
        })
    }
}
//在Vuex注入了$store,在路由注入_router
VueRouter.install=function(_Vue){

    _Vue.mixin({
        // 给每一个组件新增一个_router的属性,这个属性的属性值是VueRouter的实例
        beforeCreate(){
            // this==> 每一个组件实例
            if(this.$options&&this.$options.router){
                // 给每一个组件实例新增_router属性,属性值就是VueRouter的实例; 这是给Vm这个Vue实例新增
                this._router=this.$options.router;
            }else{
                // 给vm的组件的实例新增
                this._router=this.$parent && this.$parent._router;
            }
            // 给每一个实例添加$route属性,
            Object.defineProperty(this,"$route",{
                value:{
                    route:this._router.route// ? 这个route
                }
            });

            // 注册两个内置组件
            // router-link  router-view
            // 注册全局组件
            <router-link to="/home"></router-link>
            let child = {}
            Vue.component("router-link",{ 
                props:{
                    to:String
                },
                // template:"<div></div>",
                render(createElement){// h是一个createdElement,这个方法可以直接接受一个组件;createElement 用来创建虚拟的DOM
                    //return createElement("a",{},首页)
                    // render : 渲染函数
                    // render: 将虚拟DOM可以转成真实的DOM;这个函数返回什么,那么最终router-link就渲染成什么
                    // this==> 当前的组件实例
                    // return + 组件;可以把组件渲染成一个真实的DOM;
                    // return h(child);
                    // return <child></child>
                    // $slots
                    return <a href={`#${this.to}`}>this.$slots.default</a>
                }
            });
            // router-view : 根据页面的hash值显示对应的组件
            Vue.component("router-view",{
                render(createdElement){
                    // 这个传递一个动态的组件名字
                    return createElement(this._router.routeMap[this._router.route.path])
                }
            })
        }
    })
};
let router=new VueRouter({
    routes:[]
})
let vm = new Vue({
    router,
    render(){

    }
})
export default VueRouter;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值