Skip to content

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): () => void
javascript
// 添加顶级路由
const removeRoute = router.addRoute({
  path: '/admin',
  component: AdminPanel
})

// 添加嵌套路由
router.addRoute('admin', {
  path: 'users',
  component: UserManagement
})

// 移除路由
removeRoute()

removeRoute()

按名称移除路由。

typescript
removeRoute(name: string | symbol): void
javascript
// 移除路由
router.removeRoute('admin')

// 安全移除(先检查存在性)
if (router.hasRoute('temporary')) {
  router.removeRoute('temporary')
}

hasRoute()

检查路由是否存在。

typescript
hasRoute(name: string | symbol): boolean
javascript
// 检查路由存在性
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): () => void
javascript
// 添加认证守卫
const removeGuard = router.beforeEach((to, from) => {
  if (to.meta.requiresAuth && !isAuthenticated()) {
    return '/login'
  }
})

// 移除守卫
removeGuard()

beforeResolve()

添加全局解析守卫。

typescript
beforeResolve(guard: NavigationGuard): () => void
javascript
// 数据预加载守卫
router.beforeResolve(async (to, from) => {
  if (to.meta.requiresData) {
    await preloadData(to)
  }
})

afterEach()

添加全局后置钩子。

typescript
afterEach(guard: NavigationHookAfter): () => void
javascript
// 页面浏览统计
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): () => void
javascript
// 全局错误处理
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 })
    }
  }
}

注意事项

  1. 单例模式 - 每个应用应该只有一个路由器实例
  2. 生命周期 - 注意路由器的初始化和销毁时机
  3. 内存管理 - 及时清理不再使用的守卫和监听器
  4. 错误边界 - 为路由操作添加适当的错误处理

🎯 总结Router 接口提供了完整的路由管理能力。通过合理使用其各种方法,可以构建出强大而灵活的单页应用程序路由系统。

🚀 Vue Router - 让前端路由变得简单而强大 | 构建现代化单页应用的最佳选择