vueRouter分析
1 vue.use插件机制 vue.use()进行包裹哟一个函数,会先判断这个函数原型是否存在install的方法,如果有那么直接执行install的方法
2 vueRouter实例,创建一个class类 在class类上定义一个install的方法,里这个方法的入参是一个vue的实例,在里面会定义两个全局的组件router-link和router-view,通过插槽进行拿值. 在router-view这个全局组件中通过this.$router.current拿到当前的路径,在this. $ router.routes中的path进行匹配查到,最终渲染,但是需要注意,current这个值必须是响应式的,要不然修改current是不会触发render的函数进行重新渲染的
3 main.js全局组件挂在,通过$options拿到
在install的方法中进行vue的mixin的混入一个beforeCreate生命周期函数,通过main.js的new Vue()传入的值,通过this.$options.router取到值,挂在到vue的原型上,让所有的组件都能拿到这个值. 代码如下: 简易版的vueRouter代码
let Vue;
class VueRouter {
constructor(options){
this.current = '/'
let initPath = '/'
Vue.util.defineReactive(this,'current',initPath)
this.routes = options.routes;
this.mode = options.mode || 'hash'
this.init();
}
init(){
if(this.mode === 'hash'){
window.addEventListener('load',() => {
this.current = location.hash.slice(1)
})
window.addEventListener('hashchange',()=>{
this.current = location.hash.slice(1)
})
}else{
window.addEventListener('load',() => {
this.current = location.pathname
})
window.addEventListener('popstate',()=>{
this.current = location.pathname
})
}
}
}
VueRouter.install = function (_Vue){
Vue = _Vue
Vue.mixin({
beforeCreate(){
if(this.$options.router){
Vue.prototype.$router = this.$options.router
}
}
})
Vue.component('router-link',{
props:{
to:{
type:String,
require:true
}
},
render(h){
return h('a',{
attrs:{
href:this.to
}
},this.$slots.default)
}
})
Vue.component('router-view',{
render(h){
let current = this.$router.current;
let routes = this.$router.routes;
let com = routes.find(item => {
return current === item.path
})
return h(com.component)
}
})
}
export default VueRouter
|