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)
}
}
网友评论