简易版vue-router

index.js

// 1,实现一个插件
import vue from 'vue'
import vueRouter from './vue-router'
import Home from './Home'
import About from './About'

const routes = [{
path: '/',
component: Home
}, {
path: '/about'
component: About
}]
const router = new vueRouter({
routes
})
export default router

vue-router.js

import Link from './router-link'
import View from './router-view'
// 1.实现一个插件:挂载$router,声明两个全局组件
// 2.实现一个KVueRouter类,管理url变化
class vueRouter {
    construction ( options){
        this.$options = options
        Vue.util.defineReactive(this, 'current', '/')
    }
    window.addEventListener('hashchange',this.onHashChange.bind(this))
    window.addEventListener('load',this.onHashChange.bind(this))
    this.routerMap = {}
    this.$options.forEach((route) => {
        this.routerMap[router.path] = router
    })
    onHashChange () {
        this.current = window.location.hash.slice(1)
    }
}
vueRouter.install = (_vue){
// 保存构造函数
  Vue = _Vue
  // 挂载$router
  // 利用全局混入,在beforeCreate钩子里面获取选项
    Vue.mixin({
        beforeCreate(){
        // router只有在根实例中才存在
        if(this.$options.router){
          Vue.prototype.$router = this.$options.router
        }
      }
  })
    // 任务2:声明两个全局组件
    Vue.component('router-link', Link)
    Vue.component('router-view', View)
}
export default vueRouter

router-link.js

export default {
    props: {
        to: {
            type: String,
            required: true
        }
     }
    render(h){
    // 渲染结果:<a href="/xx">abc</a>
    // 渲染函数三个参数:标签名称,属性集合,子元素数组
    // return h('a', { attrs: { href: '#' + this.to } }, [this.$slots.default])
    // jsx写法
        return <a href={'#' + this.to}>{this.$slots.default}</a>
    }
}

router-view.js

export default {
    render (h){
        let component = null
        // 动态获取current对应的组件
        const route = this.$router.routeMap[this.$router.current]
        if(route){
              component = route.component
        }
        return h(component)
    }
}