index.js
// 1,實(shí)現(xiàn)一個(gè)插件
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.實(shí)現(xiàn)一個(gè)插件:掛載$router,聲明兩個(gè)全局組件
// 2.實(shí)現(xiàn)一個(gè)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鉤子里面獲取選項(xiàng)
Vue.mixin({
beforeCreate(){
// router只有在根實(shí)例中才存在
if(this.$options.router){
Vue.prototype.$router = this.$options.router
}
}
})
// 任務(wù)2:聲明兩個(gè)全局組件
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ù)三個(gè)參數(shù):標(biāo)簽名稱,屬性集合,子元素?cái)?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
// 動(dòng)態(tài)獲取current對(duì)應(yīng)的組件
const route = this.$router.routeMap[this.$router.current]
if(route){
component = route.component
}
return h(component)
}
}