Skip to content

useRouter | Vue Router API

概述

useRouter 是 Vue Router 的组合式 API 函数,用于在组件中访问路由器实例。它提供了编程式导航和控制路由器的能力。

语法

typescript
function useRouter(): Router

返回值

类型: Router说明: 路由器实例,包含导航方法和路由控制功能

基本用法

在组件中使用

vue
<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

// 编程式导航
function navigateToAbout() {
  router.push('/about')
}

function goBack() {
  router.back()
}
</script>

<template>
  <button @click="navigateToAbout">关于我们</button>
  <button @click="goBack">返回</button>
</template>

路由器实例方法

导航方法

push - 添加新记录

javascript
// 路径字符串
router.push('/home')

// 路径对象
router.push({ path: '/home' })

// 命名路由
router.push({ name: 'user', params: { id: 123 } })

// 带查询参数
router.push({ path: '/search', query: { q: 'vue' } })

replace - 替换当前记录

javascript
// 替换当前路由,不添加历史记录
router.replace('/login')
router.replace({ name: 'home' })

go - 前进后退

javascript
router.go(1)  // 前进一页
router.go(-1) // 后退一页
router.go(-3) // 后退三页

back / forward - 便捷方法

javascript
router.back()     // 等价于 router.go(-1)
router.forward()  // 等价于 router.go(1)

路由控制方法

addRoute - 添加路由

javascript
// 添加基础路由
router.addRoute({ path: '/new', component: NewPage })

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

removeRoute - 删除路由

javascript
// 按名称删除
router.removeRoute('user')

// 使用添加路由时返回的函数
const removeRoute = router.addRoute(routeConfig)
removeRoute()

hasRoute - 检查路由存在

javascript
if (router.hasRoute('admin')) {
  console.log('管理员路由已存在')
}

getRoutes - 获取所有路由

javascript
const allRoutes = router.getRoutes()
console.log('当前路由配置:', allRoutes)

实际应用场景

场景 1:表单提交后导航

vue
<script setup>
import { useRouter } from 'vue-router'
import { ref } from 'vue'

const router = useRouter()
const formData = ref({})

async function submitForm() {
  try {
    await api.submitForm(formData.value)
    
    // 提交成功后导航到结果页面
    router.push({ 
      name: 'success', 
      query: { submitted: true } 
    })
  } catch (error) {
    console.error('提交失败:', error)
  }
}
</script>

场景 2:权限控制导航

vue
<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

function navigateToAdmin() {
  if (userStore.isAdmin) {
    router.push('/admin')
  } else {
    router.push('/access-denied')
  }
}

function navigateWithPermission(route, requiredPermission) {
  if (authStore.hasPermission(requiredPermission)) {
    router.push(route)
  } else {
    showPermissionError()
  }
}
</script>

场景 3:动态路由管理

vue
<script setup>
import { useRouter } from 'vue-router'
import { onMounted } from 'vue'

const router = useRouter()

// 组件挂载时动态添加路由
onMounted(() => {
  if (userStore.isPremium) {
    router.addRoute({
      path: '/premium',
      component: () => import('./PremiumPage.vue')
    })
  }
})

// 组件卸载时清理路由
onUnmounted(() => {
  if (router.hasRoute('premium')) {
    router.removeRoute('premium')
  }
})
</script>

场景 4:智能导航助手

javascript
// navigation-helper.js
import { useRouter } from 'vue-router'

export function useSmartNavigation() {
  const router = useRouter()
  
  return {
    // 安全导航,处理错误
    async safeNavigate(to, options = {}) {
      try {
        const result = await router.push(to)
        
        if (result) {
          // 导航被阻止
          options.onAbort?.()
          return { success: false, reason: 'aborted' }
        }
        
        options.onSuccess?.()
        return { success: true }
      } catch (error) {
        options.onError?.(error)
        return { success: false, error }
      }
    },
    
    // 带确认的导航
    confirmNavigate(message, to) {
      if (confirm(message)) {
        router.push(to)
      }
    },
    
    // 外部链接处理
    navigateToExternal(url) {
      window.open(url, '_blank', 'noopener,noreferrer')
    }
  }
}

高级用法

导航守卫集成

vue
<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

// 添加全局前置守卫
router.beforeEach((to, from) => {
  if (to.meta.requiresAuth && !authStore.isLoggedIn) {
    return '/login'
  }
})

// 添加全局后置钩子
router.afterEach((to, from) => {
  analytics.trackPageView(to.path)
})
</script>

路由状态监听

vue
<script setup>
import { useRouter } from 'vue-router'
import { watch } from 'vue'

const router = useRouter()

// 监听路由变化
watch(
  () => router.currentRoute.value,
  (newRoute, oldRoute) => {
    console.log('路由变化:', oldRoute.path, '->', newRoute.path)
    
    // 执行路由变化相关逻辑
    if (newRoute.meta.requiresAnalytics) {
      trackPageView(newRoute)
    }
  },
  { immediate: true }
)
</script>

编程式导航封装

javascript
// navigation-service.js
import { useRouter } from 'vue-router'

export class NavigationService {
  constructor() {
    this.router = useRouter()
  }
  
  // 导航到用户主页
  navigateToUserProfile(userId) {
    this.router.push({
      name: 'user-profile',
      params: { id: userId }
    })
  }
  
  // 导航到搜索页面
  navigateToSearch(query, filters = {}) {
    this.router.push({
      path: '/search',
      query: {
        q: query,
        ...filters
      }
    })
  }
  
  // 带状态保存的导航
  navigateWithState(to, state) {
    this.router.push({
      ...to,
      state: state
    })
  }
  
  // 获取当前路由状态
  getCurrentState() {
    return this.router.currentRoute.value.state
  }
}

最佳实践

1. 错误处理

javascript
async function safeNavigation(to) {
  try {
    const result = await router.push(to)
    
    if (result) {
      // 处理导航被阻止的情况
      handleNavigationFailure(result)
    }
  } catch (error) {
    console.error('导航错误:', error)
    showErrorNotification('页面加载失败')
  }
}

2. 性能优化

javascript
// 防抖导航,避免快速连续点击
function createDebouncedNavigation(delay = 300) {
  let timeoutId = null
  
  return function debouncedNavigate(to) {
    if (timeoutId) {
      clearTimeout(timeoutId)
    }
    
    timeoutId = setTimeout(() => {
      router.push(to)
      timeoutId = null
    }, delay)
  }
}

3. 类型安全(TypeScript)

typescript
import { useRouter } from 'vue-router'

// 定义类型安全的导航函数
interface NavigationTargets {
  home: never
  userProfile: { id: number }
  search: { query: string; category?: string }
}

function useTypedRouter() {
  const router = useRouter()
  
  return {
    push<T extends keyof NavigationTargets>(
      name: T, 
      params: NavigationTargets[T]
    ) {
      return router.push({ name, params })
    }
  }
}

注意事项

  1. 组件上下文 - 只能在 setup()<script setup> 中使用
  2. 响应式 - 路由器实例本身不是响应式的,但 currentRoute 是响应式的
  3. 单例 - 在整个应用中路由器实例是单例的
  4. SSR 兼容 - 在服务器端渲染中需要特殊处理

兼容性

  • Vue 3.0+
  • 组合式 API
  • TypeScript 支持

🚀 提示useRouter 为程序化路由控制提供了强大的工具,合理使用可以创建出更加动态和交互性强的单页应用程序。

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