1、實(shí)現(xiàn)插件
2、routes選項(xiàng)解析:生成一個(gè)Map,把path和component映射起來
3、監(jiān)控url上的hash變化:響應(yīng)hash變化,獲取并顯示相對的組件
4、生成兩個(gè)全局組件:router-link,router-view
只是實(shí)現(xiàn)了一個(gè)單層的路由,比起真正的vue-router來說還有很多的功能沒有實(shí)現(xiàn)。
let Vue;
class VueRouter{
constructor(options){
//routes選項(xiàng)
this.$options = options
this.routeMap = {}
//路由響應(yīng)式變化,利用vue響應(yīng)式
this.app = new Vue({
data:{
current:'/'
}
})
}
init(){
//1、監(jiān)聽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是標(biāo)簽子元素
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實(shí)例
if(this.$options.router){
Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
},
})
}
export default VueRouter