vue-router插件的实现原理
let Vue;
class mRouter{
constructor(options){
// vue的配置项
this.$options = options
console.log(options)
// 缓存path和route映射关系 避免重复循环
this.routeMap = {}
this.$options.routes.forEach(route => { this.routeMap[route.path] = route });
// 添加一个响应的current
Vue.util.defineReactive(this, 'current', '/')
// 监听路由变化
window.addEventListener('hashchange',this.onHashChange.bind(this))
//监听网站刷新
window.addEventListener('load',this.onHashChange.bind(this))
}
onHashChange() { this.current = window.location.hash.slice(1) }
}
mRouter.install = function(_vue){
Vue = _vue;
Vue.mixin({
beforeCreate(){
// 只有根组件拥有router选项
if(this.$options.router){
Vue.prototype.$router = this.$options.router;
console.log(this)
}
}
})
//为什么要用混入方式写?主要原因是use代码在前,Router实例创建在后,而install逻辑又需要用到该实例
//创建router-link和router-view组件
Vue.component('router-link',{
props:{
to: {
type: String,
required: true
}
},
render(h){
// 两种方式都行
// return <a href={'#'+this.to}>{this.$slots.default}</a>;
return h('a',{attrs:{href:'#'+this.to}},[this.$slots.default])
}
})
Vue.component('router-view',{
render(h){
// 动态获取对应组件
const {routeMap, current} = this.$router
const component = routeMap[current].component;
return h(component)
}
})
}
export default mRouter
然后在vue.cli创建的项目中router/index.js中导入
//原来的
import Vue from 'vue'
import VueRouter from 'vue-router' //这个地方引入自己写的vue-router插件 import VueRouter from './mRoute'
import Home from '../views/Home.vue'