分析源码
import { createRouter, createWebHashHistory,createWebHistory } from 'vue-router'
const route = []
const router = createRouter({
history: createWebHashHistory(),
routes: route
})
export default router
从源码来看我们要手写一个路由主要就是要实现一个createRouter
方法和一个createWebHashHistory
方法或者createWebHistory
方法,我们这边选择实现createWebHashHistory
,最后能够让路径和组件能够一一映射,一个简单的路由就算实现了。
createRouter
const ROUTER_KEY = '_router_'
class Router {
constructor(options) {
this.history = options.history
this.routes = options.routes
this.current = ref(this.history.url)
this.history.bindEvents(() => {
this.current.value = window.location.hash.slice(1)
})
}
install(app) {
app.provide(ROUTER_KEY, this)
// 注册全局组件router-link
app.component('router-link', RouterLink)// 声明全局组件
app.component('router-view', RouterView)
}
}
export function createRouter(options) {
return new Router(options)
}
首先是createRouter(),我们用一个class。我们知道我们调用createRouter()时需要传入一个对象,里面有两个值,一个是routes数组,另外一个是history。我们在构造时就根据这个结构去构造。
路由的跳转是根据浏览器的url地址进行的,所以我们在此将他存下来并且赋值为一个响应式的属性,方便在url地址变化时及时做出相应的变化。
然后要调用掉history里面的一个方法,这个方法是获取当前地址。
这个install(app)
就单纯是因为只有install之后的才能够被vue给use掉。app.component()
是注册为全局组件,这个就是我们自己的router-view
和router-link
。
useRouter
export function useRouter() {
return inject(ROUTER_KEY)
}
注入路由,就是得到了整个Router类。
RouterView
<template>
<component :is="component"></component>
</template>
<script setup>
import { computed } from 'vue';
import { useRouter } from '../myRouter';
const router = useRouter(); // 在当前组件注入了router
const component = computed(() => {
const route = router.routes.find((route) => {
return route.path === router.current.value
})
return route ? route.component : null
})
</script>
RouterView 的作用就是从routes数组中根据你当前的url启用相应的代码,首先就是在得到useRouter的结果也就是整个Router类,我们需要根据这个得到routes数组。然后就是根据当前的url去找对应的组件,并且放进对应的位置。
RouterLink
<template>
<a :href="'#' + to">
<slot></slot>
</a>
</template>
<script setup>
defineProps({
to: {
String,
required: true
}
})
</script>
<style lang="css" scoped></style>
RouterLink其实就是一个a标签,动态绑定了一个to属性,根据这个to属性跳往对应的url地址。
createWebHashHistory()
export function createWebHashHistory() {
function bindEvents(fn) {
window.addEventListener('hashchange', fn)//监听浏览器地址改变事件
}
return {
bindEvents,
url: window.location.hash.slice(1) || '/'// 获取当前地址
}
}
createWebHashHistory()就是要持续的获取当前的url地址并返回出去。
假如您也和我一样,在准备春招。欢迎加我微信shunwuyu,这里有几十位一心去大厂的友友可以相互鼓励,分享信息,模拟面试,共读源码,齐刷算法,手撕面经。来吧,友友们!