实现简单的mini-router hash模式

82 阅读1分钟
import { ref, inject } from 'vue'
const ROUTER_KEY = '__router__'

function createRouter(options) {
    return new Router(options)
}

function useRouter() {
    return inject(ROUTER_KEY)
}

function createWebHashHistory() {
    function bindEvents(fn) {
        // 为window对象添加hashchange事件监听器,当URL的hash值发生变化时,执行传入的函数fn
        window.addEventListener('hashchange', fn)
    }
    console.log(window.location.hash);
    return {
        bindEvents,
        url: window.location.hash.slice(1) || '/'
    }
}
import RouterLink from "./RouterLink.vue";
import RouterView from "./RouterView.vue";
class Router {
    constructor(options) {
        // 将传入的options对象中的history属性赋值给当前实例的history属性
        this.history = options.history
        // 将传入的options对象中的routes属性赋值给当前实例的routes属性
        this.routes = options.routes
        // 创建一个响应式引用,初始值为history对象的url属性,并赋值给当前实例的current属性
        this.current = ref(this.history.url)

        // 调用history对象的bindEvents方法,传入一个回调函数
        this.history.bindEvents(() => {
            // 在回调函数中,将window.location.hash.slice(1)的结果赋值给current属性的value
            this.current.value = window.location.hash.slice(1)
        })
    }
    install(app) {
        app.provide(ROUTER_KEY, this)
        app.component('router-link', RouterLink)
        app.component('router-view', RouterView)
    }
}

export { createRouter, useRouter, createWebHashHistory }
<template>
    <a :href="'#'+props.to">
        <slot />
    </a>
</template>

<script setup>
import {defineProps} from 'vue'
let props = defineProps({
    to:{type:String,required:true}
})
</script>
<template>
  <component :is="component"></component>
</template>
<script setup>
import { computed } from "vue";
import { useRouter } from "../grouter/index";

let router = useRouter();
console.log(router);
const component = computed(() => {
  const route = router.routes.find(
    (route) => route.path === router.current.value
  );
  return route ? route.component : null;
});
console.log(component);
</script>

// import { createWebHistory, createRouter } from "vue-router";
import { createWebHashHistory, createRouter } from "./grouter/index";
// createRouter 用来新建路由事例, createWebHashHistory 用来配置我们内部使用 hash
// 模式的路由,也就是 url 上会通过 # 来区分
import Home from '../pages/Home.vue'
import About from '../pages/About.vue'
const routes = [
    {
        path: '/',
        component: Home
        // component: () => import('../pages/home.vue')
    },
    {
        path: '/about',
        component: About
        // component: () => import('../pages/about.vue')
    },
]

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

export default router