let Vue;
export default class VueRouter {
constructor(options) {
this.$options = options;
// 定义routeMap 实现path到component的映射关系
this.routeMap = {};
// 利用vue实现当前路径的响应式,所以vue-router是和vue强耦合只能在vue中使用
this.app = new Vue({
data: {
// 保存当前的值
current: "/"
}
});
}
init() {
// 1.事件监听
this.bindEvents();
// 2.创建路由的映射
this.createRouteMap();
// 3.声明全局组件
this.initComponent();
}
bindEvents() {
// 监听hash变化
window.addEventListener("hashchange", this.onHashChange.bind(this));
// 监听页面加载
window.addEventListener("load", this.onHashChange.bind(this));
}
onHashChange() {
this.app.current = window.location.hash.slice(1) || "/";
}
// 解析routes选项
createRouteMap() {
this.$options.routes.forEach(item => {
this.routeMap[item.path] = item.component;
});
}
//
initComponent() {
// 全局声明组件
Vue.component("router-link", {
props: { to: { type: String, required: true } },
render() {
// 1. render生成虚拟dom
// 2. 描述渲染的dom结构
// h(tag, data, children)
return <a href={this.to}>{this.$slots.default}</a>; // jsx语法
// return h("a", { attrs: { href: this.to } }, [this.$slots.default]);
}
});
Vue.component("router-view", {
render: h => {
// this 指向VueRouter实例
const component = this.routeMap[this.app.current];
return h(component);
}
});
}
}
// 插件要求实现install方法 vue的插件使用的时候都要vue.use() 调用install 并且vue把自己传递进来
VueRouter.install = function(_Vue) {
Vue = _Vue;
// 混入:挂载$router
Vue.mixin({
beforeCreate() {
// this 指当前组件的实例
if (this.$options.router) {
// 挂载到根组件、子组件创建的时候原型上存在
Vue.prototype.$router = this.$options.router;
// 初始化router
this.$options.router.init();
}
}
});
};