let _Vue = null;
export default class VueRouter {
static install(Vue) {
// 1、判断当前插件是否已经被安装
if (VueRouter.install.installed) {
return;
}
VueRouter.install.installed = true
// 2、把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3、把创建 Vue 实例时候传入的 router 注入到全部 Vue 实例上
// _Vue.prototype.$router = this.$options.router
// 混入
_Vue.mixin({
beforeCreate() {
// 只在 new Vue() 实例中执行,不在组件中执行
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router
}
}
})
}
constructor(options) {
this.options = options;
this.routeMap = {};
// 创建一个响应式对象 data
this.data = _Vue.observable({
current: '/'
})
this.init();
}
init() {
this.createRouteMap();
this.initComponents(_Vue);
this.initEvent()
}
createRouteMap() {
// 遍历所有路由规则,把路由规则解析成键值对的形式,存储到 routeMap 中
this.options.routes.forEach(route => {
this.routeMap[route.path] = route.component
console.log(this.routeMap)
});
}
initComponents(Vue) {
const self = this;
Vue.component("router-link", {
props: {
to: String
},
// slot 插槽
// template: '<a :href="to"><slot></slot></a>',
//运行时版本的Vue需要自己写render函数
render(h) {
return h('a', {
attrs: {
href: this.to
},
on: {
click: this.clickhander
}
}, [this.$slots.default])
},
methods: {
clickhander(e) {
history.pushState({}, "", this.to)
this.$router.data.current = this.to
e.preventDefault()
}
}
})
Vue.component("router-view", {
render(h) {
const cm = self.routeMap[self.data.current]
console.log(self.routeMap);
return h(cm)
}
})
}
initEvent() {
//
window.addEventListener("popstate", () => {
this.data.current = window.location.pathname
})
}
}