Router 接口 | Vue Router API
概述
Router 接口是 Vue Router 的核心接口,代表整个路由器的实例。它提供了路由导航、路由管理、守卫控制等核心功能。
接口定义
typescript
interface Router {
// 当前路由信息
readonly currentRoute: Ref<RouteLocationNormalized>
// 路由配置
readonly options: RouterOptions
// 导航方法
push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>
replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>
go(delta: number): void
back(): void
forward(): void
// 路由管理
addRoute(parentName: string | symbol, route: RouteRecordRaw): () => void
addRoute(route: RouteRecordRaw): () => void
removeRoute(name: string | symbol): void
hasRoute(name: string | symbol): boolean
getRoutes(): RouteRecordNormalized[]
// 守卫控制
beforeEach(guard: NavigationGuard): () => void
beforeResolve(guard: NavigationGuard): () => void
afterEach(guard: NavigationHookAfter): () => void
// 工具方法
isReady(): Promise<void>
onError(handler: (error: any, to: RouteLocationNormalized, from: RouteLocationNormalized) => any): () => void
install(app: App): void
}核心属性
currentRoute
类型: Ref<RouteLocationNormalized>说明: 响应式的当前路由信息对象
typescript
// 访问当前路由信息
const route = router.currentRoute.value
console.log('当前路径:', route.path)
console.log('路由参数:', route.params)options
类型: RouterOptions说明: 路由器的配置选项
typescript
// 访问路由器配置
console.log('历史模式:', router.options.history)
console.log('路由数量:', router.options.routes.length)导航方法
push()
添加新的历史记录并导航到指定路由。
typescript
push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>参数:
to: 目标路由位置
返回值: 导航结果 Promise
javascript
// 基本用法
await router.push('/home')
await router.push({ path: '/user/123' })
await router.push({ name: 'user', params: { id: 123 } })
// 错误处理
try {
const result = await router.push('/protected')
if (result) {
console.log('导航被阻止:', result)
}
} catch (error) {
console.error('导航错误:', error)
}replace()
替换当前历史记录并导航到指定路由。
typescript
replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>javascript
// 登录后替换当前记录
await router.replace('/dashboard')
// 避免在历史记录中留下登录页面
router.push('/login') // 用户登录后
router.replace('/profile') // 替换登录记录go() / back() / forward()
控制浏览器历史记录导航。
javascript
router.go(1) // 前进一页
router.go(-1) // 后退一页
router.go(-3) // 后退三页
router.back() // 后退(等价于 go(-1))
router.forward() // 前进(等价于 go(1))路由管理方法
addRoute()
动态添加路由配置。
typescript
addRoute(parentName: string | symbol, route: RouteRecordRaw): () => void
addRoute(route: RouteRecordRaw): () => voidjavascript
// 添加顶级路由
const removeRoute = router.addRoute({
path: '/admin',
component: AdminPanel
})
// 添加嵌套路由
router.addRoute('admin', {
path: 'users',
component: UserManagement
})
// 移除路由
removeRoute()removeRoute()
按名称移除路由。
typescript
removeRoute(name: string | symbol): voidjavascript
// 移除路由
router.removeRoute('admin')
// 安全移除(先检查存在性)
if (router.hasRoute('temporary')) {
router.removeRoute('temporary')
}hasRoute()
检查路由是否存在。
typescript
hasRoute(name: string | symbol): booleanjavascript
// 检查路由存在性
if (router.hasRoute('premium-features')) {
// 显示高级功能
showPremiumUI()
}getRoutes()
获取所有路由记录。
typescript
getRoutes(): RouteRecordNormalized[]javascript
// 获取所有路由
const allRoutes = router.getRoutes()
// 过滤和搜索路由
const publicRoutes = allRoutes.filter(route =>
!route.meta?.requiresAuth
)
const adminRoutes = allRoutes.filter(route =>
route.path.startsWith('/admin')
)守卫控制方法
beforeEach()
添加全局前置守卫。
typescript
beforeEach(guard: NavigationGuard): () => voidjavascript
// 添加认证守卫
const removeGuard = router.beforeEach((to, from) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
return '/login'
}
})
// 移除守卫
removeGuard()beforeResolve()
添加全局解析守卫。
typescript
beforeResolve(guard: NavigationGuard): () => voidjavascript
// 数据预加载守卫
router.beforeResolve(async (to, from) => {
if (to.meta.requiresData) {
await preloadData(to)
}
})afterEach()
添加全局后置钩子。
typescript
afterEach(guard: NavigationHookAfter): () => voidjavascript
// 页面浏览统计
router.afterEach((to, from) => {
analytics.trackPageView(to.fullPath)
})
// 页面标题更新
router.afterEach((to) => {
document.title = to.meta.title || '默认标题'
})工具方法
isReady()
等待路由器准备就绪。
typescript
isReady(): Promise<void>javascript
// 等待路由器初始化完成
await router.isReady()
// 然后执行路由相关操作
initializeApp()onError()
添加错误处理程序。
typescript
onError(handler: (error: any, to: RouteLocationNormalized, from: RouteLocationNormalized) => any): () => voidjavascript
// 全局错误处理
router.onError((error, to, from) => {
console.error('路由错误:', error)
showErrorNotification('页面加载失败')
})实际应用场景
场景 1:动态权限路由
javascript
class DynamicRouter {
constructor(router) {
this.router = router
}
// 根据用户权限动态添加路由
setupRoutesForUser(user) {
// 移除可能存在的旧路由
this.cleanupRoutes()
// 添加基础路由
this.addPublicRoutes()
// 根据权限添加功能路由
if (user.roles.includes('admin')) {
this.addAdminRoutes()
}
if (user.permissions.includes('billing')) {
this.addBillingRoutes()
}
}
addPublicRoutes() {
this.router.addRoute({
path: '/',
component: Home
})
}
addAdminRoutes() {
this.router.addRoute({
path: '/admin',
component: AdminLayout,
children: [
{ path: 'users', component: UserManagement },
{ path: 'settings', component: SystemSettings }
]
})
}
cleanupRoutes() {
const routes = this.router.getRoutes()
routes.forEach(route => {
if (route.meta?.dynamic) {
this.router.removeRoute(route.name)
}
})
}
}场景 2:智能导航服务
javascript
class NavigationService {
constructor(router) {
this.router = router
this.setupNavigationAnalytics()
}
// 智能导航,包含确认和错误处理
async smartNavigate(to, options = {}) {
const {
confirmMessage,
onSuccess,
onError,
fallbackRoute = '/'
} = options
// 确认导航
if (confirmMessage && !confirm(confirmMessage)) {
return { success: false, reason: 'user_cancelled' }
}
try {
const result = await this.router.push(to)
if (result) {
// 导航被守卫阻止
return this.handleNavigationFailure(result, fallbackRoute)
}
onSuccess?.()
return { success: true }
} catch (error) {
onError?.(error)
return { success: false, error }
}
}
// 设置导航分析
setupNavigationAnalytics() {
this.router.afterEach((to, from) => {
this.trackNavigation(to, from)
})
}
trackNavigation(to, from) {
// 发送导航数据到分析平台
analytics.track('navigation', {
from: from.path,
to: to.path,
duration: Date.now() - this.lastNavigationTime
})
}
}场景 3:路由状态管理
javascript
class RouteStateManager {
constructor(router) {
this.router = router
this.navigationHistory = []
this.setupHistoryTracking()
}
setupHistoryTracking() {
// 跟踪所有导航
this.router.afterEach((to, from) => {
this.navigationHistory.push({
timestamp: Date.now(),
from: from.path,
to: to.path,
fullPath: to.fullPath
})
// 限制历史记录长度
if (this.navigationHistory.length > 100) {
this.navigationHistory.shift()
}
})
}
// 获取导航历史
getNavigationHistory(limit = 10) {
return this.navigationHistory.slice(-limit)
}
// 查找最近的特定路由
findRecentRoute(pattern) {
return this.navigationHistory
.slice()
.reverse()
.find(record => record.to.match(pattern))
}
// 回到上一个特定页面
async goBackTo(pattern) {
const target = this.findRecentRoute(pattern)
if (target) {
await this.router.push(target.fullPath)
}
}
}最佳实践
1. 错误处理模式
javascript
// 统一的导航错误处理
async function safeNavigation(router, to) {
try {
const result = await router.push(to)
if (result) {
switch (result.type) {
case NavigationFailureType.cancelled:
console.warn('导航被取消')
break
case NavigationFailureType.duplicated:
console.warn('重复导航')
break
default:
console.error('未知导航错误', result)
}
return false
}
return true
} catch (error) {
console.error('导航异常:', error)
return false
}
}2. 性能优化
javascript
// 批量路由操作
class RouteBatchProcessor {
constructor(router) {
this.router = router
this.pendingOperations = []
}
// 批量添加路由
batchAddRoutes(routes) {
const removeFunctions = []
routes.forEach(route => {
const removeFn = this.router.addRoute(route)
removeFunctions.push(removeFn)
})
// 返回批量移除函数
return () => {
removeFunctions.forEach(fn => fn())
}
}
// 延迟执行路由操作
deferRouteOperation(operation) {
return new Promise(resolve => {
requestAnimationFrame(() => {
const result = operation()
resolve(result)
})
})
}
}3. 类型安全(TypeScript)
typescript
// 类型安全的路由器包装器
interface TypedRouter {
push<T extends keyof RouteMap>(
name: T,
params?: RouteMap[T]['params'],
query?: RouteMap[T]['query']
): Promise<NavigationFailure | void | undefined>
replace<T extends keyof RouteMap>(
name: T,
params?: RouteMap[T]['params'],
query?: RouteMap[T]['query']
): Promise<NavigationFailure | void | undefined>
}
function createTypedRouter(router: Router): TypedRouter {
return {
push(name, params, query) {
return router.push({ name, params, query })
},
replace(name, params, query) {
return router.replace({ name, params, query })
}
}
}注意事项
- 单例模式 - 每个应用应该只有一个路由器实例
- 生命周期 - 注意路由器的初始化和销毁时机
- 内存管理 - 及时清理不再使用的守卫和监听器
- 错误边界 - 为路由操作添加适当的错误处理
🎯 总结:
Router接口提供了完整的路由管理能力。通过合理使用其各种方法,可以构建出强大而灵活的单页应用程序路由系统。