vue-router history模式简单实现

165 阅读1分钟

vue-router是什么

vue-router是vue的插件,作用是实现路由

vue-router实现,主要包含的几个部分

  • vueRouter类
  • 因为是vue的插件,需要实现install方法
  • 实现router-link组件
  • 实现router-veiw组件
  • 实现路由切换后自动加载对应组件

VueRouter构造函数

// 接收路由配置,初始化配置
class VueRouter {
    constructor(options){
    	this.options = options 
        this.routerMap = {} //储存路由表
        this.data = _Vue.observable({
            current: '/'
        })
        this.createRoureMap()
        this.initEvent()
    }
}

静态方法install,接收参数当前vue实列,后续创建组件需要用到这个实列

let _Vue = null //放到全局保存接收到的vue实列
class VueRouter {
    static install(vue){
        if( Vue.install.installed && _Vue === vue ) return
        VueRouter.install.installed = true
        _Vue = vue
        
        //把当前组件的路由对象赋值给每一个vue实列
        vue.mixin({
            beforeCreated(){
                if( this.$options.router ){
                    _Vue.prototype.$router = this.$options.router   
                }
            }
        })
    }
}

createRouteMap 生产路由表

createRoureMap(){
    this.options.routes.forEach(route=>{
        this.routerMap[route.path] = route.component
    })
}

initComponents 初始化路由组件 router-link router-view

initComponents(){
    _Vue.component('router-link',{
        props:{
            to: String
        },
        methods:{
            handlerClick(e){
                window.history.pushState({},'',this.to) //改变导航栏地址
                this.$router.data.current = this.to //改变当前路由地址
                e.preventDefault() //阻止啊标签默认事件
            }
        },
        render(h){
            return h('a',{
                    attrs: {
                        href: this.to
                    },
                    on:{
                        click: handlerClick
                    }
                },[this.$slots.default])
            }
        )
        const self = this
        _Vue.component('router-view',{
            render(h){
                return h(self.routerMap[self.data.current])
            }
        })
    }
}

注册popState事件,点击浏览器前进后退时加载路由

initEvent(){
    window.addeventlistener('popState',()=>{
        this.data.current = window.location.pathname
    },false)
}