Vue Router 通过抽象 History API 封装层统一处理路由,提供 createWebHistory、createWebHashHistory 和 createMemoryHistory 三种工厂函数,返回具有一致接口的 History 实例,支持跨环境(浏览器/SSR/测试)的 URL 解析、事件监听与导航同步。

Vue Router 并不直接暴露原始的 history.pushState 或 popstate,而是通过抽象的 History API 封装层统一处理路由跳转、历史导航与 URL 同步。这个封装层的核心作用,是让开发者无需关心底层环境差异(比如是否支持 HTML5 History、是否运行在浏览器或 Node 环境、是否启用 hash),只需声明路由配置,就能获得一致的行为。
History 实例的工厂化创建
Vue Router 把不同模式的历史管理逻辑拆分为独立的构造函数:
-
createWebHistory():基于history.pushState/replaceState和popstate事件,生成可操作真实浏览器历史栈的实例; -
createWebHashHistory():监听hashchange事件,读写location.hash,兼容所有现代浏览器(包括 IE10+); -
createMemoryHistory():纯内存实现,不依赖 URL,适用于 SSR、测试或非浏览器环境(如 Electron 渲染进程未挂载 DOM 时)。
它们都返回一个符合 RouterHistory 类型的对象,拥有统一接口:push()、replace()、go()、listen()、destroy()。这意味着上层路由逻辑(如 router.push)完全解耦于具体实现。
URL 解析与序列化的标准化
不同模式下,URL 结构差异明显(/user/1 vs #!/user/1),但 Vue Router 内部始终将路径归一为「逻辑路径」(即去掉 #、base 前缀后的纯净 path):
立即学习“前端免费学习笔记(深入)”;
- 在
createWebHashHistory中,它自动截取location.hash.slice(1)作为当前路径; - 在
createWebHistory中,它通过new URL(location.href).pathname提取路径,并结合base配置做归一化; - 所有路径解析结果都会经过
normalizePath()处理(如合并重复斜杠、处理..),确保路由匹配逻辑稳定。
查询参数(query)和哈希片段(hash)也由统一的 parseQuery/stringifyQuery 处理,默认使用原生 URLSearchParams,但允许自定义(例如适配旧版 IE 或兼容 qs 格式)。
事件监听与导航同步机制
无论哪种模式,Vue Router 都通过 listen() 方法注册统一的导航回调:
- Hash 模式调用
window.addEventListener('hashchange', ...),并在初始化时手动触发一次hashchange模拟首屏加载; - History 模式监听
popstate,同时在push/replace调用后主动触发内部状态更新,避免因事件延迟导致视图滞后; - Memory 模式则完全靠函数调用驱动,
listen()返回一个取消监听的函数,push()直接同步更新内部 state 并执行回调。
这种设计让 router.isReady()、beforeEach、scrollBehavior 等能力能在所有模式下可靠工作,不需要条件分支判断环境。
服务端与客户端的无缝衔接(SSR 场景)
在服务端渲染中,浏览器 API 不可用,createWebHistory 会报错。Vue Router 的解决方案是:
- 服务端使用
createMemoryHistory()初始化 router,并传入初始 URL(如req.url); - 客户端 hydrate 时,根据实际运行环境自动切换为
createWebHistory或createWebHashHistory; - 通过
router.push()和router.replace()的幂等性设计,确保首屏路由状态与服务端输出一致,避免水合 mismatch。
整个过程对业务代码透明——你写的 { path: '/user/:id', component: User } 在服务端和客户端被解析、匹配、激活的方式完全相同。


















