useRoute | Vue Router API
概述
useRoute 是 Vue Router 的组合式 API 函数,用于在组件中访问当前路由信息。它返回一个响应式的路由对象,包含当前路由的各种详细信息。
语法
typescript
function useRoute(): RouteLocationNormalized返回值
类型: RouteLocationNormalized说明: 当前路由的标准化信息对象,包含路径、参数、查询等信息
基本用法
在组件中访问路由信息
vue
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 访问路由信息
console.log('当前路径:', route.path)
console.log('路由参数:', route.params)
console.log('查询参数:', route.query)
console.log('哈希值:', route.hash)
</script>
<template>
<div>
<p>当前页面: {{ route.path }}</p>
<p>用户ID: {{ route.params.id }}</p>
<p>搜索关键词: {{ route.query.q }}</p>
</div>
</template>路由对象属性
核心属性
path
类型: string说明: 当前路由的路径(不含查询参数和哈希)
javascript
// 对于 /users/123?page=2#section
route.path // '/users/123'fullPath
类型: string说明: 完整路径(包含查询参数和哈希)
javascript
// 对于 /users/123?page=2#section
route.fullPath // '/users/123?page=2#section'params
类型: Record<string, string | string[]>说明: 路由参数对象
javascript
// 对于路由 /users/:id/posts/:postId
route.params // { id: '123', postId: '456' }query
类型: Record<string, string | string[]>说明: 查询参数对象
javascript
// 对于 /search?q=vue&category=docs
route.query // { q: 'vue', category: 'docs' }hash
类型: string说明: 当前 URL 的哈希部分(带 #)
javascript
// 对于 /page#section
route.hash // '#section'路由匹配信息
matched
类型: RouteRecordNormalized[]说明: 匹配的路由记录数组(用于嵌套路由)
javascript
route.matched.forEach(record => {
console.log('匹配的路由:', record.path)
})meta
类型: Record<string, any>说明: 路由元信息(合并了所有匹配路由的 meta)
javascript
// 访问路由元信息
if (route.meta.requiresAuth) {
// 需要认证的逻辑
}name
类型: string | symbol | undefined | null说明: 路由名称(如果定义了的话)
javascript
if (route.name === 'user-profile') {
// 用户资料页的特殊逻辑
}实际应用场景
场景 1:动态页面内容
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
// 基于路由参数动态加载内容
const userId = computed(() => route.params.id)
const pageTitle = computed(() => {
if (route.name === 'user-profile') {
return `用户 ${userId.value} 的资料`
}
return '默认标题'
})
</script>
<template>
<div>
<h1>{{ pageTitle }}</h1>
<user-profile :user-id="userId" />
</div>
</template>场景 2:搜索和过滤功能
vue
<script setup>
import { useRoute } from 'vue-router'
import { watch, ref } from 'vue'
const route = useRoute()
const searchResults = ref([])
// 监听查询参数变化
watch(
() => route.query,
async (newQuery) => {
if (newQuery.q) {
// 执行搜索
searchResults.value = await api.search(newQuery.q, newQuery)
}
},
{ immediate: true }
)
// 获取当前筛选条件
const currentFilters = computed(() => ({
category: route.query.category,
sort: route.query.sort || 'relevance',
priceRange: route.query.priceRange
}))
</script>场景 3:面包屑导航
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
// 生成面包屑数据
const breadcrumbs = computed(() => {
return route.matched
.filter(record => record.meta?.breadcrumb)
.map(record => ({
text: record.meta.breadcrumb,
path: record.path,
active: record === route.matched[route.matched.length - 1]
}))
})
</script>
<template>
<nav class="breadcrumb">
<router-link
v-for="item in breadcrumbs"
:key="item.path"
:to="item.path"
:class="{ active: item.active }"
>
{{ item.text }}
</router-link>
</nav>
</template>场景 4:权限和功能控制
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
// 基于路由元信息控制功能
const canEdit = computed(() =>
route.meta.permissions?.includes('edit') ?? false
)
const showAdminPanel = computed(() =>
route.meta.requiresAdmin && userStore.isAdmin
)
// 页面特定的样式类
const pageClass = computed(() =>
`page-${route.name} theme-${route.meta.theme || 'light'}`
)
</script>
<template>
<div :class="pageClass">
<admin-panel v-if="showAdminPanel" />
<edit-button v-if="canEdit" />
<!-- 页面内容 -->
</div>
</template>高级用法
响应式路由监听
vue
<script setup>
import { useRoute } from 'vue-router'
import { watchEffect } from 'vue'
const route = useRoute()
// 自动响应路由变化
watchEffect(() => {
// 当路由参数变化时重新加载数据
if (route.params.id) {
loadUserData(route.params.id)
}
// 更新页面标题
if (route.meta.title) {
document.title = `${route.meta.title} - 我的应用`
}
// 发送页面浏览统计
analytics.trackPageView(route.fullPath)
})
</script>路由参数类型转换
javascript
import { useRoute } from 'vue-router'
import { computed } from 'vue'
export function useRouteParams() {
const route = useRoute()
return {
// 将字符串参数转换为数字
userId: computed(() => parseInt(route.params.id) || 0),
page: computed(() => parseInt(route.query.page) || 1),
// 处理数组参数
categories: computed(() => {
const categoryParam = route.query.categories
return Array.isArray(categoryParam)
? categoryParam
: categoryParam ? [categoryParam] : []
}),
// 布尔参数处理
isPreview: computed(() => route.query.preview === 'true')
}
}路由状态管理
javascript
// route-state.js
import { useRoute } from 'vue-router'
import { reactive, watch } from 'vue'
export function useRouteState() {
const route = useRoute()
const state = reactive({
// 从路由初始化状态
currentView: route.name,
queryParams: { ...route.query },
routeParams: { ...route.params },
// 状态变更历史
history: []
})
// 监听路由变化,更新状态
watch(
() => route.fullPath,
(newPath, oldPath) => {
state.currentView = route.name
state.queryParams = { ...route.query }
state.routeParams = { ...route.params }
// 记录状态变更
state.history.push({
from: oldPath,
to: newPath,
timestamp: Date.now()
})
}
)
return state
}最佳实践
1. 参数验证和默认值
javascript
function useSafeRouteParams() {
const route = useRoute()
return {
// 带验证的用户ID
userId: computed(() => {
const id = parseInt(route.params.id)
return id > 0 ? id : null
}),
// 带默认值的分页
pagination: computed(() => ({
page: Math.max(1, parseInt(route.query.page) || 1),
limit: Math.min(50, parseInt(route.query.limit) || 10),
sort: route.query.sort || 'created_at'
})),
// 安全的搜索词
searchTerm: computed(() => {
const term = route.query.q || ''
return term.trim().slice(0, 100) // 限制长度
})
}
}2. 性能优化
javascript
// 避免在模板中直接使用 route.params.id
// 不推荐:
<template>
<div>{{ route.params.id }}</div>
</template>
// 推荐:
<script setup>
const route = useRoute()
const userId = computed(() => route.params.id)
</script>
<template>
<div>{{ userId }}</div>
</template>3. 类型安全(TypeScript)
typescript
import { useRoute } from 'vue-router'
// 定义路由参数类型
interface UserRouteParams {
id: string
}
interface UserRouteQuery {
tab?: string
edit?: string
}
export function useUserRoute() {
const route = useRoute()
// 类型安全的参数访问
const params = route.params as UserRouteParams
const query = route.query as UserRouteQuery
return {
userId: params.id,
activeTab: query.tab || 'profile',
isEditMode: query.edit === 'true'
}
}注意事项
- 响应式依赖 - 在模板中使用路由属性时,确保使用计算属性或响应式引用
- 性能考虑 - 避免在渲染函数中频繁访问路由对象
- SSR 兼容 - 服务器端渲染时注意路由状态的同步
- 类型安全 - 使用 TypeScript 增强参数类型检查
兼容性
- Vue 3.0+
- 组合式 API
- TypeScript 支持
- SSR 兼容
🎯 总结:
useRoute是访问当前路由信息的标准方式,它提供了响应式的路由数据访问。通过合理使用路由信息,可以构建出高度动态和交互性强的组件。