index.js
// 1,實現(xiàn)一個插件
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.實現(xiàn)一個插件:掛載$router,聲明兩個全局組件
// 2.實現(xiàn)一個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){
// 保存構(gòu)造函數(shù)
Vue = _Vue
// 掛載$router
// 利用全局混入粤剧,在beforeCreate鉤子里面獲取選項
Vue.mixin({
beforeCreate(){
// router只有在根實例中才存在
if(this.$options.router){
Vue.prototype.$router = this.$options.router
}
}
})
// 任務(wù)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){
// 渲染結(jié)果:<a href="/xx">abc</a>
// 渲染函數(shù)三個參數(shù):標簽名稱梗肝,屬性集合窖铡,子元素數(shù)組
// 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
// 動態(tài)獲取current對應(yīng)的組件
const route = this.$router.routeMap[this.$router.current]
if(route){
component = route.component
}
return h(component)
}
}