1、实现插件
2、routes选项解析:生成一个Map,把path和component映射起来
3、监控url上的hash变化:响应hash变化,获取并显示相对的组件
4、生成两个全局组件:router-link,router-view
只是实现了一个单层的路由,比起真正的vue-router来说还有很多的功能没有实现。
let Vue;
class VueRouter{
constructor(options){
//routes选项
this.$options = options
this.routeMap = {}
//路由响应式变化,利用vue响应式
this.app = new Vue({
data:{
current:'/'
}
})
}
init(){
//1、监听url变化
this.bindEvent()
//2、映射路由map
this.createRouteMap(this.$options)
//3、生成全局组件
this.initComponent()
}
bindEvent(){
window.addEventListener('load',this.onHashChange.bind(this))
window.addEventListener('hashchange',this.onHashChange.bind(this))
}
onHashChange(){
//截取路由,只做了单层路由 #/index
this.app.current = window.location.hash.slice(1) || '/'
}
createRouteMap(options){
options.routes.forEach(item =>{
this.routeMap[item.path] = item.component
})
//console.log(this.routeMap)
}
initComponent(){
//router-link,router-view
//<router-link>xxx</router-link>
Vue.component('router-link',{
props:{to:{type:String}},
render(h) {
//生成虚拟dom
//h(tag,data,children) children是标签子元素
const vdom = h('a', { attrs: { href: '#' + this.to } }, [this.$slots.default])
console.log(vdom)
return h('a',{attrs:{href:'#'+this.to}},[this.$slots.default])
},
})
Vue.component('router-view',{
render:(h)=> {
const component = this.routeMap[this.app.current]
return h(component)
},
})
}
}
VueRouter.install = function(_Vue) {
Vue = _Vue
Vue.mixin({
beforeCreate() {
//这里的this是Vue实例
if(this.$options.router){
Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
},
})
}
export default VueRouter