Vue Router API 参考手册 📚
🎯 完整指南:Vue Router 4.x 核心 API 详解,从基础到高级的完整参考手册
欢迎来到 Vue Router 的 API 世界!这里是你的路由开发宝典,包含了所有你需要的函数、组件和类型定义。
🚀 快速导航
🔧 核心函数
- createRouter() - 创建路由器实例
- createWebHistory() - HTML5 历史模式
- createWebHashHistory() - Hash 历史模式
- createMemoryHistory() - 内存历史模式
🎨 组件
- RouterView - 路由视图组件
- RouterLink - 路由链接组件
🪝 Composition API
- useRouter() - 获取路由器实例
- useRoute() - 获取当前路由
- useLink() - 链接功能钩子
🛡️ 导航守卫
- onBeforeRouteUpdate() - 路由更新守卫
- onBeforeRouteLeave() - 路由离开守卫
🔧 核心函数详解
createRouter()
创建路由器实例的核心函数,是一切路由功能的起点。
typescript
function createRouter(options: RouterOptions): Router🎯 基础用法
javascript
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
})🔥 高级配置
javascript
const router = createRouter({
history: createWebHistory('/app/'),
routes: [...routes],
// 🎨 滚动行为
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
},
// 🔍 严格模式
strict: true,
// 🎯 敏感模式
sensitive: true
})📋 RouterOptions 配置项
| 属性 | 类型 | 描述 | 默认值 |
|---|---|---|---|
history | RouterHistory | 历史模式实例 | 必需 |
routes | RouteRecordRaw[] | 路由配置数组 | [] |
scrollBehavior | Function | 滚动行为函数 | undefined |
parseQuery | Function | 查询参数解析函数 | undefined |
stringifyQuery | Function | 查询参数序列化函数 | undefined |
strict | boolean | 严格模式 | false |
sensitive | boolean | 大小写敏感 | false |
createWebHistory()
创建 HTML5 历史模式,现代 Web 应用的首选。
typescript
function createWebHistory(base?: string): RouterHistory🎯 基础用法
javascript
import { createWebHistory } from 'vue-router'
// 默认基础路径
const history = createWebHistory()
// 自定义基础路径
const history = createWebHistory('/my-app/')
// 动态基础路径
const history = createWebHistory(process.env.BASE_URL)🌟 实际应用场景
javascript
// 🏢 企业级应用
const enterpriseHistory = createWebHistory('/enterprise/')
// 🛒 电商平台
const shopHistory = createWebHistory('/shop/')
// 📱 移动端应用
const mobileHistory = createWebHistory('/m/')createWebHashHistory()
创建 Hash 历史模式,无需服务器配置的简单选择。
typescript
function createWebHashHistory(base?: string): RouterHistory🎯 基础用法
javascript
import { createWebHashHistory } from 'vue-router'
// 基础 Hash 模式
const history = createWebHashHistory()
// URL: https://example.com/#/
// 带基础路径的 Hash 模式
const history = createWebHashHistory('/folder/')
// URL: https://example.com/folder/#/💡 适用场景
javascript
// 🔧 内部工具
const toolHistory = createWebHashHistory()
// 📊 数据看板
const dashboardHistory = createWebHashHistory('/dashboard/')
// 🧪 原型开发
const prototypeHistory = createWebHashHistory()createMemoryHistory()
创建内存历史模式,主要用于 SSR 和测试环境。
typescript
function createMemoryHistory(base?: string): RouterHistory🎯 基础用法
javascript
import { createMemoryHistory } from 'vue-router'
// SSR 环境
const history = createMemoryHistory()
// 测试环境
const testHistory = createMemoryHistory('/test/')🧪 测试应用
javascript
// 单元测试中的路由器
function createTestRouter(initialPath = '/') {
const history = createMemoryHistory()
const router = createRouter({
history,
routes: testRoutes
})
// 设置初始路径
router.push(initialPath)
return router
}🎨 组件详解
RouterView
显示当前路由对应组件的核心组件。
typescript
const RouterView: Component🎯 基础用法
vue
<template>
<div id="app">
<nav>
<RouterLink to="/">首页</RouterLink>
<RouterLink to="/about">关于</RouterLink>
</nav>
<!-- 路由视图 -->
<RouterView />
</div>
</template>🔥 高级用法
vue
<template>
<!-- 命名视图 -->
<RouterView name="header" />
<RouterView /> <!-- 默认视图 -->
<RouterView name="footer" />
<!-- 带过渡效果 -->
<router-view v-slot="{ Component, route }">
<transition :name="route.meta.transition || 'fade'">
<component :is="Component" :key="route.path" />
</transition>
</router-view>
<!-- 带 KeepAlive -->
<router-view v-slot="{ Component, route }">
<keep-alive :include="route.meta.keepAlive">
<component :is="Component" :key="route.path" />
</keep-alive>
</router-view>
</template>🎨 RouterView 插槽
vue
<template>
<RouterView v-slot="{ Component, route }">
<div class="page-wrapper">
<!-- 页面标题 -->
<h1>{{ route.meta.title }}</h1>
<!-- 面包屑导航 -->
<nav class="breadcrumb">
<span v-for="crumb in route.matched" :key="crumb.path">
{{ crumb.meta.title }}
</span>
</nav>
<!-- 组件内容 -->
<component :is="Component" />
</div>
</RouterView>
</template>RouterLink
创建导航链接的组件,自动处理激活状态。
typescript
const RouterLink: Component🎯 基础用法
vue
<template>
<!-- 字符串路径 -->
<RouterLink to="/home">首页</RouterLink>
<!-- 对象路径 -->
<RouterLink :to="{ path: '/user', query: { id: 123 } }">
用户详情
</RouterLink>
<!-- 命名路由 -->
<RouterLink :to="{ name: 'user', params: { id: 123 } }">
用户资料
</RouterLink>
</template>🔥 高级功能
vue
<template>
<!-- 自定义激活类名 -->
<RouterLink
to="/products"
active-class="is-active"
exact-active-class="is-exact-active"
>
产品列表
</RouterLink>
<!-- 替换历史记录 -->
<RouterLink to="/login" replace>
登录
</RouterLink>
<!-- 自定义标签 -->
<RouterLink to="/external" custom v-slot="{ href, navigate }">
<a :href="href" @click="navigate" target="_blank">
外部链接
</a>
</RouterLink>
</template>🎨 RouterLink 属性
| 属性 | 类型 | 描述 | 默认值 |
|---|---|---|---|
to | RouteLocationRaw | 目标路由 | 必需 |
replace | boolean | 是否替换历史记录 | false |
activeClass | string | 激活时的类名 | 'router-link-active' |
exactActiveClass | string | 精确激活时的类名 | 'router-link-exact-active' |
custom | boolean | 是否自定义渲染 | false |
🪝 Composition API 详解
useRouter()
在 Composition API 中获取路由器实例。
typescript
function useRouter(): Router🎯 基础用法
vue
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
// 编程式导航
const goToHome = () => {
router.push('/')
}
const goBack = () => {
router.back()
}
</script>🔥 高级应用
vue
<script setup>
import { useRouter } from 'vue-router'
import { ref, onMounted } from 'vue'
const router = useRouter()
const isLoading = ref(false)
// 带加载状态的导航
const navigateWithLoading = async (to) => {
isLoading.value = true
try {
await router.push(to)
} catch (error) {
console.error('导航失败:', error)
} finally {
isLoading.value = false
}
}
// 条件导航
const conditionalNavigate = (to, condition) => {
if (condition) {
router.push(to)
} else {
router.push('/unauthorized')
}
}
</script>useRoute()
在 Composition API 中获取当前路由信息。
typescript
function useRoute(): RouteLocationNormalizedLoaded🎯 基础用法
vue
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
// 响应式路由信息
const userId = computed(() => route.params.id)
const searchQuery = computed(() => route.query.q)
const currentPath = computed(() => route.path)
</script>
<template>
<div>
<h1>用户 ID: {{ userId }}</h1>
<p>搜索关键词: {{ searchQuery }}</p>
<p>当前路径: {{ currentPath }}</p>
</div>
</template>🔥 高级应用
vue
<script setup>
import { useRoute, useRouter } from 'vue-router'
import { watch, ref } from 'vue'
const route = useRoute()
const router = useRouter()
const pageData = ref(null)
// 监听路由变化
watch(
() => route.params.id,
async (newId, oldId) => {
if (newId !== oldId) {
await loadPageData(newId)
}
},
{ immediate: true }
)
// 基于路由的数据加载
const loadPageData = async (id) => {
try {
pageData.value = await fetchUserData(id)
} catch (error) {
router.push('/404')
}
}
</script>useLink()
创建自定义链接组件的底层钩子。
typescript
function useLink(props: UseLinkOptions): UseLinkReturn🎯 基础用法
vue
<script setup>
import { useLink } from 'vue-router'
const props = defineProps({
to: {
type: [String, Object],
required: true
}
})
const { href, navigate, isActive, isExactActive } = useLink(props)
</script>
<template>
<a
:href="href"
@click="navigate"
:class="{
active: isActive,
'exact-active': isExactActive
}"
>
<slot />
</a>
</template>🔥 自定义链接组件
vue
<!-- CustomLink.vue -->
<script setup>
import { useLink } from 'vue-router'
import { computed } from 'vue'
const props = defineProps({
to: [String, Object],
variant: {
type: String,
default: 'default'
}
})
const { href, navigate, isActive } = useLink(props)
const linkClass = computed(() => [
'custom-link',
`custom-link--${props.variant}`,
{ 'custom-link--active': isActive.value }
])
</script>
<template>
<a
:href="href"
:class="linkClass"
@click="navigate"
>
<slot />
</a>
</template>
<style scoped>
.custom-link {
@apply px-4 py-2 rounded transition-colors;
}
.custom-link--primary {
@apply bg-blue-500 text-white hover:bg-blue-600;
}
.custom-link--active {
@apply ring-2 ring-blue-300;
}
</style>🛡️ 导航守卫详解
onBeforeRouteUpdate()
在当前路由更新时触发的组合式 API 守卫。
typescript
function onBeforeRouteUpdate(updateGuard: NavigationGuard): void🎯 基础用法
vue
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'
const userData = ref(null)
onBeforeRouteUpdate(async (to, from) => {
// 路由参数变化时重新加载数据
if (to.params.id !== from.params.id) {
userData.value = await fetchUser(to.params.id)
}
})
</script>🔥 高级应用
vue
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
import { ref, nextTick } from 'vue'
const isLoading = ref(false)
const error = ref(null)
onBeforeRouteUpdate(async (to, from, next) => {
// 显示加载状态
isLoading.value = true
error.value = null
try {
// 预加载数据
await preloadRouteData(to)
// 等待 DOM 更新
await nextTick()
next()
} catch (err) {
error.value = err.message
next(false) // 取消导航
} finally {
isLoading.value = false
}
})
</script>onBeforeRouteLeave()
在离开当前路由时触发的组合式 API 守卫。
typescript
function onBeforeRouteLeave(leaveGuard: NavigationGuard): void🎯 基础用法
vue
<script setup>
import { onBeforeRouteLeave } from 'vue-router'
import { ref } from 'vue'
const hasUnsavedChanges = ref(false)
onBeforeRouteLeave((to, from, next) => {
if (hasUnsavedChanges.value) {
const answer = window.confirm('您有未保存的更改,确定要离开吗?')
if (answer) {
next()
} else {
next(false)
}
} else {
next()
}
})
</script>🔥 高级应用
vue
<script setup>
import { onBeforeRouteLeave } from 'vue-router'
import { ref, computed } from 'vue'
const formData = ref({})
const originalData = ref({})
const isSaving = ref(false)
const hasChanges = computed(() => {
return JSON.stringify(formData.value) !== JSON.stringify(originalData.value)
})
onBeforeRouteLeave(async (to, from, next) => {
if (!hasChanges.value) {
next()
return
}
const action = await showSaveDialog()
switch (action) {
case 'save':
isSaving.value = true
try {
await saveFormData()
next()
} catch (error) {
showErrorMessage('保存失败')
next(false)
} finally {
isSaving.value = false
}
break
case 'discard':
next()
break
case 'cancel':
default:
next(false)
break
}
})
const showSaveDialog = () => {
return new Promise((resolve) => {
// 显示自定义对话框
// 返回 'save', 'discard', 或 'cancel'
})
}
</script>🔍 工具函数
isNavigationFailure()
检查导航是否失败的工具函数。
typescript
function isNavigationFailure(
error: any,
type?: NavigationFailureType
): error is NavigationFailure🎯 基础用法
javascript
import { isNavigationFailure, NavigationFailureType } from 'vue-router'
router.push('/some-route').catch(failure => {
if (isNavigationFailure(failure)) {
console.log('导航失败:', failure.message)
}
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
console.log('重复导航')
}
})🔥 错误处理策略
javascript
const handleNavigationError = (failure) => {
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
// 导航被中止
showMessage('导航被取消')
} else if (isNavigationFailure(failure, NavigationFailureType.cancelled)) {
// 导航被取消
showMessage('导航被中断')
} else if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
// 重复导航
console.log('重复导航,忽略')
} else {
// 其他错误
showErrorMessage('导航失败: ' + failure.message)
}
}📋 类型定义
核心类型
RouteLocationRaw
用户级别的路由位置定义:
typescript
type RouteLocationRaw =
| string
| RouteLocationPathRaw
| RouteLocationNamedRawRouteRecordRaw
路由记录的原始定义:
typescript
type RouteRecordRaw =
| RouteRecordSingleView
| RouteRecordSingleViewWithChildren
| RouteRecordMultipleViews
| RouteRecordMultipleViewsWithChildren
| RouteRecordRedirectNavigationGuard
导航守卫函数类型:
typescript
type NavigationGuard = (
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext
) => NavigationGuardReturn | Promise<NavigationGuardReturn>实用类型示例
typescript
// 🎯 路由配置类型
interface AppRouteRecord extends RouteRecordRaw {
meta?: {
title?: string
requiresAuth?: boolean
roles?: string[]
icon?: string
}
}
// 🔒 权限守卫类型
type AuthGuard = (
to: RouteLocationNormalized,
from: RouteLocationNormalized
) => boolean | Promise<boolean>
// 📊 路由统计类型
interface RouteAnalytics {
path: string
visitCount: number
averageTime: number
lastVisited: Date
}🎯 最佳实践
1. 类型安全的路由配置
typescript
// 定义路由名称枚举
enum RouteNames {
HOME = 'home',
USER_PROFILE = 'user-profile',
PRODUCT_DETAIL = 'product-detail'
}
// 类型安全的路由配置
const routes: AppRouteRecord[] = [
{
path: '/',
name: RouteNames.HOME,
component: Home,
meta: { title: '首页' }
},
{
path: '/user/:id',
name: RouteNames.USER_PROFILE,
component: UserProfile,
meta: { title: '用户资料', requiresAuth: true }
}
]2. 智能路由工厂
typescript
class RouterFactory {
static create(options: {
mode: 'hash' | 'history' | 'memory'
base?: string
routes: RouteRecordRaw[]
}) {
const historyMap = {
hash: () => createWebHashHistory(options.base),
history: () => createWebHistory(options.base),
memory: () => createMemoryHistory(options.base)
}
return createRouter({
history: historyMap[options.mode](),
routes: options.routes
})
}
}3. 路由中间件系统
typescript
// 路由中间件接口
interface RouteMiddleware {
name: string
handler: NavigationGuard
}
// 中间件管理器
class MiddlewareManager {
private middlewares: Map<string, RouteMiddleware> = new Map()
register(middleware: RouteMiddleware) {
this.middlewares.set(middleware.name, middleware)
}
async execute(names: string[], to: RouteLocationNormalized, from: RouteLocationNormalized) {
for (const name of names) {
const middleware = this.middlewares.get(name)
if (middleware) {
const result = await middleware.handler(to, from, () => {})
if (result === false) return false
}
}
return true
}
}🚀 下一步学习
掌握了 API 基础后,建议深入学习:
💡 专家提示:熟练掌握这些 API 是成为 Vue Router 专家的必经之路。建议在实际项目中多加练习,结合具体场景深入理解每个 API 的使用时机和最佳实践!
这份 API 参考手册将伴随你的 Vue Router 开发之旅,助你构建出色的单页应用! 🎉