由于时间问题,暂时先把代码完整的贴上来,感兴趣的朋友可以自行研究或收藏。等我那时有时间的时候,对专栏文章进行排序,并逐一讲解代码
一、对外暴露的入口文件index.js
import Vue from 'vue'
import VueRouter from "./kvue-router";
// 使用路由插件 - 插件一定要实现install方法(静态)
Vue.use(VueRouter);
// 配置路由参数
const router = new VueRouter({
routers: [{
path: "/",
name: "Home",
component: () => import("../views/Home.vue")
},{
path: "/about",
name: "Home",
component: () => import("../views/About.vue")
}]
});
// 暴露路由
export default router;
二、路由处理实例
// 我们自己的路由器
let Vue;
// 1.VueRouter类,是一个插件
class VueRouter {
constructor(options) {
this.$options = options;
// 由于地址的hash值会不断地发生改变,然后展示相应路由上的内容,因此需要不断地触发对应路由组件的渲染函数
// 为此,我们将this.current定义为一个响应式数据,并给予一个默认的初始值
Vue.util.defineReactive(this, "current", window.location.hash.slice(1) || "/");
// 通过hash值的变化,监听URL的变化
window.addEventListener("hashchange", () => {
this.current = window.location.hash.slice(1);
});
}
}
// 插件要实现instal方法才能被Vue引入
VueRouter.install = function (_Vue) {
// 保存构造函数的引用
Vue = _Vue;
// 挂载$router到Vue原型 - 组件之间的路由导航(全局开放)
// 需要注意的是,由于Vue引入路由的时候,router并没有被实例化
// 所以我们可以利用全局混入,延迟执行下面代码,这样就可以获取router实例
Vue.mixin({
beforeCreate() {
if (this.$options.router) {
Vue.prototype.$router = this.$options.router;
}
}
});
// 声明两个全局组件router-link、router-view
Vue.component("router-link", {
props: {
to: {
type: String,
require: true
}
},
// 不能使用template属性定义字符串模板
// 因为当前项目是再Vue-Cli环境下使用Wepacke打包的,所以并没有编译器
render(h) {
// this指向当前的组件实例
return h("a", { attrs: { href: `#${this.to}` } }, this.$slots.default)
}
});
Vue.component("router-view", {
render(h) {
// this.$router.current表示的是当前的路由地址
// 如果想要触发render函数,那么this.$router.current数值一定得是响应式数值
// 如果current的值是响应式的话,我们就可以根据它的值获取路由表中对应组件并且渲染它
let component = null;
const route = this.$router.$options.routers.find((route) => {
return route.path === this.$router.current;
});
if(route) {
component = route.component;
}
return h(component)
}
});
}
export default VueRouter;