手写一个mini版vue3-router

122 阅读1分钟

废话不多说,就是没有废话,一名合格的前端工程师直接看代码,实现hash简易路由

mini-vue3-router.js

目的:通过hashchange事件获取hash路径

import { ref, inject } from 'vue'
import RouterView from './RouterView.vue'
import RouterLink from './RouterLink.vue'
const ROUTER_KEY = '__router__'

const createRouter = (options) => {
  return new Router(options)
}
const createWebHashHistory = (fn) => {
  return {
    bindEvent(fn) {
      window.addEventListener('hashchange', fn)
    },
    url: window.location.hash.slice(1) || '/',
  }
}
const useRouter = () => {
  return inject(ROUTER_KEY)
}
class Router {
  constructor(options) {
    this.history = options.history
    this.routes = options.routes
    this.current = ref(this.history.url)
    this.history.bindEvent(() => {
      this.current.value = window.location.hash.slice(1)
    })
  }
  install(app) {
    app.provide(ROUTER_KEY, this)
    app.component('router-view', RouterView)
    app.component('router-link', RouterLink)
  }
}

export { createRouter, useRouter, createWebHashHistory }

router-view

目的: 使用动态组件根据路径切换组件

<template>
    <component :is="com"></component>
</template>
<script setup>
import { computed} from 'vue'
import { useRouter } from './grouter'
let router = useRouter()
let com = computed( () => {
    const route = router.routes.find((routes) => routes.path === router.current.value)
    return route? route.component : null
    
})
</script>

目的: 改变hash路径的值

router-link

<template>
    <a :href="'#' + props.to ">
        <slot></slot>
    </a>
</template>
<script setup>
import { defineProps } from 'vue'
let props = defineProps({
    to: {
        type: String,
        required: true
    }
})
</script>