功能介绍:
1、只为1级路由之间跳转,适合看源码之前看看逻辑
2、此模式为 hash 模式;history 模式跟这个大差不差
直接看代码,提示全在代码里
/**
* 最简陋router:只支持一级路由,适合看 vue-router 源码之前看看
* 此模式为 hash 模式,history 模式 大差不差
*/
let _Vue = null
export default class VueRouter {
// 因为vue挂载是使用Vue.use():如果是函数,则直接调用;如果是对象则会去找这个对象里面的install方法;第一个参数是Vue实例;
static install(Vue) {
// 判断插件是否安装
if (VueRouter.install.installed) return
// 如果未安装则设置为已安装-防止多次挂载
VueRouter.install.installed = true
// 把vue构造函数记录到全局变量
_Vue = Vue
// 把创建Vue实例时候传入的router对象注入到Vue实例上
_Vue.mixin({
beforeCreate() {
if (this.$options.router){
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
constructor(options) {
// 传递过来的配置项
this.options = options;
// 路由地图
this.routerMap = {};
// 动态路由数据
this.data = _Vue.observable({
current: location.hash
})
}
// 初始化
init() {
this.createRouteMap()
this.initComponents(_Vue)
this.initEvent()
}
// 初始化事件
initEvent() {
// 当浏览器触发前进和后退的时候触发函数
onhashchange = () => {
this.data.current = window.location.hash
}
}
// 创建路由地图
createRouteMap(arr = this.options, index = 'routes', path = '') {
// 遍历所有的路由规则,把路由规则解析成键值对的形式,存储到routerMap中
arr[index].forEach(route => {
// 处理子集不写 / 和 写/ 的情况
let pathEnd = `${path}${route.path.indexOf('/') === 0?'':'/'}${route.path}`
this.routerMap[pathEnd] = route.component
// 如果发现有子集,则递归调用
if (Array.isArray(route.children)) {
this.createRouteMap(route, 'children', pathEnd)
}
});
}
// 初始化组件
initComponents(Vue) {
let _this = this
Vue.component('router-link', {
props: {
to: String
},
/**
* 开启template这行需要在vue.config.js 配置 runtimeCompiler: true。意为 运行时编译模板。官网有介绍 。开启后请重新启动项目。
* 官网地址 https://cli.vuejs.org/zh/config/#runtimecompiler
*/
// template: '<a :href="to"><slot></slot></a>'
render (h) {
return h('a', {
attrs: {
href: '#' + this.to
},
on: {
click: this.clickHandle
}
// 插槽
}, [this.$slots.default])
},
methods: {
clickHandle() {
// 设置当前hash给动态路由-联动更新页面
this.$router.data.current = window.location.hash
}
},
})
Vue.component('router-view', {
render(h) {
// 这里this指向当前vue,而不是咱们的vue router
return h(_this.routerMap[_this.data.current.replace('#', '')||'/'])
}
})
}
}
引用
直接vue cli 创建一个项目 修改引入路径即可(注:history模式得删除掉,此只支持hash模式)
import Vue from "vue";
import Home from "../views/Home.vue";
import VueRouters from '../vue-router'
Vue.use(VueRouters)
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue")
},
];
const router = new VueRouters({
routes
})
export default router;