

在日常开发中,路由系统是必不可少的一部分。几天前,我的项目出现了一个导航守卫失效的问题,折腾了好几个小时才找到原因。于是,我决定彻底搞懂 Vue Router 的实现原理,分享出来给大家避坑!下面我们深入剖析 Vue Router 的各个模块,确保每一个细节都能看懂。

通过 createRouter(options) 初始化路由对象时,我们需要传入配置:
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About },
],
});这个函数会:
history 或 hash。路由对象是 Vue Router 的核心,它包含以下几部分:
currentRoute:记录当前路径,随导航自动更新。addRoute / getRoutes:动态添加或获取路由信息。push / replace:改变当前路径。beforeEach:注册全局前置守卫。isReady:判断路由是否初始化完毕。Vue Router 的核心在于路径与视图的关系,它通过路径解析器建立路径和组件的映射。
传入的路由配置:
const routes = [
{
path: '/',
component: Home,
children: [
{ path: 'home-child', component: HomeChild },
],
},
{ path: '/about', component: About },
];解析后生成的匹配器结构:
[
{
re: /^\/home-child\/?$/i,
record: { path: '/home-child' },
parent: { re: /^\/\/?$/i },
},
{
re: /^\/\/?$/i,
record: { path: '/' },
parent: undefined,
},
{
re: /^\/about\/?$/i,
record: { path: '/about' },
parent: undefined,
},
];re:基于路径生成的正则表达式,用于匹配导航路径。record:原始的路由配置信息。parent:记录父级路由信息,支持嵌套导航。调用 router.push('/about') 时:
resolve 方法获取路径的目标信息。 name,从 matcherMap 快速查找。path,遍历 matchers 使用正则匹配。Promise 链。history.pushState,更新 currentRoute。Vue Router 提供了三种模式:history、hash 和 abstract。这里以 history 模式为例:
设置导航方法:通过 useHistoryStateNavigation 实现 push 和 replace。
history.pushState(state, '', url);监听路径变化:当用户点击浏览器的前进/后退按钮时,通过 popstate 事件触发导航逻辑。
嵌套渲染:通过注入 depth 标识,依次匹配 currentRoute.matched[depth]。
示例:
currentRoute.matched[0]; // 父级组件
currentRoute.matched[1]; // 子级组件本质是一个普通的点击事件处理:
router.push(to);导航守卫是 Vue Router 的亮点,支持在路径变化前后执行自定义逻辑。
包装守卫函数:通过 guardToPromiseFn 将守卫函数包装成 Promise:
const promise = new Promise((resolve) => {
guard(to, from, resolve);
});执行顺序:根据官方文档定义的解析流程,逐步执行。
使用 reduce 串联所有守卫:
return guards.reduce(
(promise, guard) => promise.then(() => guard()),
Promise.resolve()
);useRouter通过 inject 获取路由对象:
export function useRouter() {
return inject(routerKey)!;
}useRoute获取当前路径对象:
export function useRoute() {
return inject(routeLocationKey)!;
}至此,Vue Router 的实现原理已经拆解得非常详细。如果还有不明白的地方,可以留言提问!希望这篇文章能帮你快速掌握 Vue Router 的核心逻辑!