实现简单的vue-router之hash模式

vue-router的组成部分:

/**
 * router分两部分一部分包含:options--记录构造函数中传入的对象(路由规则对象),
 * data--current--当前路由地址--响应式 vue.observable,
 * routerMap---记录路由地址和组件的对应关系,
 * 一部分包含:constructor,install(void),init(void) --调用后面方法的,initEvent(void),creatRouteMap(void),initComponents(void)
 * **/
let _Vue=null
export default class Router{
   static install(Vue){
      //vue.use初始化router的时候会调用内部的install方法,
       // 1.判断当前插件是否已经安装.
       if(Router.install.installed) return
          Router.install.installed=true
       // 2.vue构造函数记录到全局变量
       _Vue=Vue
       //3.将创建vue实例时传入的router对象注入到vue实例上
       //mixnin
       _Vue.mixin({
           beforeCreate() {
               if(this.$options.router){ //组件不执行Vue实例可执行,因为实例的$options中含有router属性组件中没有
                   _Vue.prototype.$router=this.$options.router
                  this.$options.router.init()
               }
           }
       })
    }
   constructor(options){ //初始化参数
        this.options=options
        this.routerMap={}
        this.data=_Vue.observable({
            current:'/'
        })
    }
    init(){
       this.creatRouteMap()
        this.initComponents(_Vue)
        this.initEvent()
    }
    creatRouteMap(){
       //遍历路由规则把路由规则解析成键值对的形式,存储
        this.options.routes.forEach(route=>{
            this.routerMap[route.path]=route.component
        })
    }
    initEvent(){
        window.addEventListener('hashchange',()=>{ //hash模式监控hash变化进行数据处理
            let hash=window.location.hash.replace('#','')
            this.data.current=hash
        })
    }
    initComponents(Vue){//实现router-link,router-view
        Vue.component('router-link',{
            props:{
                to:String
            },
            render(h){
                return h('a',{
                    attrs:{
                        href:this.to==='/'? '/':'#/'+this.to
                    },
                    on:{
                        click:this.clickHandler
                    }
                },[this.$slots.default])
            },
            methods:{
                clickHandler(e){
                    history.pushState({},'',this.to==='/'? '/':'#/'+this.to)
                     this.$router.data.current=this.to==='/'? '/':'/'+this.to
                     e.preventDefault()
                }
            }
        })
        let self=this
        Vue.component('router-view',{ //h函数可以创建虚拟dom,将路由地址(组件)转换成虚拟dom,由于此时data.current是响应式数据因此此时current变化会影响component取值
            render(h){
               const component= self.routerMap[self.data.current]
                return h(component)
            }
        })
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值