Appearance
Vue Router 架构分析
整体架构
Vue Router 采用基于路由匹配和导航的架构,通过路由器、路由记录和导航守卫管理应用路由。
┌─────────────────────────────────────────────┐
│ Vue Router │
├─────────────────────────────────────────────┤
│ 1. Router (路由器) │
│ - Route Matching (路由匹配) │
│ - Navigation (导航) │
│ - History Management (历史管理) │
├─────────────────────────────────────────────┤
│ 2. Route Record (路由记录) │
│ - Path (路径) │
│ - Component (组件) │
│ - Children (子路由) │
├─────────────────────────────────────────────┤
│ 3. Navigation Guards (导航守卫) │
│ - Global Guards (全局守卫) │
│ - Route Guards (路由守卫) │
│ - Component Guards (组件守卫) │
└─────────────────────────────────────────────┘核心组件
1. Router
路由器负责路由匹配和导航。
职责:
- 路由匹配
- 导航管理
- 历史管理
关键方法:
javascript
class Router {
constructor(options) {
this.routes = options.routes || []
this.currentRoute = null
this.history = createHistory(options.mode)
}
// 初始化路由
init(app) {
// 初始化逻辑
}
// 导航到指定路由
push(location) {
this.history.push(location)
}
// 替换当前路由
replace(location) {
this.history.replace(location)
}
// 返回上一页
go(n) {
this.history.go(n)
}
}优势:
- 灵活:支持多种路由模式
- 强大:支持嵌套路由
- 可扩展:支持自定义路由
2. Route Record
路由记录表示单个路由配置。
职责:
- 存储路由配置
- 管理子路由
- 匹配路径
关键方法:
javascript
class RouteRecord {
constructor(record) {
this.path = record.path
this.component = record.component
this.name = record.name
this.children = record.children || []
this.props = record.props
this.meta = record.meta || {}
}
// 添加子路由
addChild(record) {
this.children.push(new RouteRecord(record))
}
// 匹配路径
match(path) {
// 匹配逻辑
}
}优势:
- 简单:简单的路由配置
- 灵活:支持嵌套路由
- 可扩展:支持自定义属性
3. Navigation Guards
导航守卫用于控制导航流程。
职责:
- 全局守卫
- 路由守卫
- 组件守卫
关键方法:
javascript
// 全局前置守卫
router.beforeEach((to, from, next) => {
// 守卫逻辑
next()
})
// 全局后置钩子
router.afterEach((to, from) => {
// 钩子逻辑
})
// 路由独享守卫
{
path: '/user',
component: User,
beforeEnter: (to, from, next) => {
// 守卫逻辑
next()
}
}
// 组件内守卫
export default {
beforeRouteEnter(to, from, next) {
// 守卫逻辑
next()
},
beforeRouteUpdate(to, from, next) {
// 守卫逻辑
next()
},
beforeRouteLeave(to, from, next) {
// 守卫逻辑
next()
}
}优势:
- 灵活:支持多种守卫类型
- 强大:支持导航控制
- 可组合:守卫可以组合使用
路由匹配
路径匹配
javascript
function matchPath(path, routePath) {
// 简单匹配
if (path === routePath) {
return { path, params: {} }
}
// 动态参数匹配
const paramNames = []
const regexPath = routePath.replace(/:([^/]+)/g, (_, name) => {
paramNames.push(name)
return '([^/]+)'
})
const regex = new RegExp(`^${regexPath}$`)
const match = path.match(regex)
if (match) {
const params = {}
paramNames.forEach((name, i) => {
params[name] = match[i + 1]
})
return { path, params }
}
return null
}嵌套路由匹配
javascript
function matchNestedRoutes(path, routes) {
const segments = path.split('/').filter(Boolean)
let currentRoutes = routes
const matchedRoutes = []
for (const segment of segments) {
let matched = null
for (const route of currentRoutes) {
const result = matchPath(segment, route.path)
if (result) {
matched = { route, params: result.params }
break
}
}
if (!matched) {
return null
}
matchedRoutes.push(matched)
currentRoutes = matched.route.children || []
}
return matchedRoutes
}历史管理
Hash 模式
javascript
class HashHistory {
constructor() {
window.addEventListener('hashchange', this.handleHashChange.bind(this))
}
push(path) {
window.location.hash = path
}
replace(path) {
const url = new URL(window.location)
url.hash = path
window.history.replaceState(null, '', url)
}
go(n) {
window.history.go(n)
}
handleHashChange() {
// 处理 hash 变化
}
}History 模式
javascript
class HTML5History {
constructor() {
window.addEventListener('popstate', this.handlePopState.bind(this))
}
push(path) {
window.history.pushState(null, '', path)
}
replace(path) {
window.history.replaceState(null, '', path)
}
go(n) {
window.history.go(n)
}
handlePopState() {
// 处理 popstate 事件
}
}性能优化
1. 路由懒加载
javascript
const routes = [
{
path: '/user',
component: () => import('./views/User.vue')
}
]2. 路由预加载
javascript
router.beforeEach((to, from, next) => {
if (to.matched.length) {
to.matched.forEach(record => {
if (typeof record.component === 'function') {
record.component()
}
})
}
next()
})3. 路由缓存
javascript
const cachedComponents = new Map()
function loadComponent(loader) {
if (cachedComponents.has(loader)) {
return Promise.resolve(cachedComponents.get(loader))
}
return loader().then(component => {
cachedComponents.set(loader, component)
return component
})
}总结
Vue Router 的架构体现了以下特点:
- 声明式:使用声明式路由配置
- 组件化:路由与组件绑定
- 灵活性:支持多种路由模式
- 可扩展:支持自定义路由
理解 Vue Router 的架构有助于更好地使用和优化 Vue Router。
参考资源

扫描二维码关注"架构师AI杜"公众号,获取更多技术内容和最新动态
