
Vue Router V4
- 40 installs
- 2 repo stars
- Updated July 29, 2026
- full-statck-skills/vue-skills
Guidance for Vue Router v4 route configuration, nested routes, navigation guards and Composition API integration in Vue 3.
About
Provides Vue Router v4 guidance for routing setup, guards, dynamic matching, history modes and useRouter/useRoute in Vue 3. A developer uses it when routing a Vue 3 application.
- Covers global/per-route/in-component navigation guards
- Includes lazy loading, history modes and Composition API usage
Vue Router V4 by the numbers
- 40 all-time installs (skills.sh)
- Ranked #1,377 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Jul 30, 2026 (Skillselion catalog sync)
npx skills add https://github.com/full-statck-skills/vue-skills --skill vue-router-v4Add your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 40 |
|---|---|
| repo stars | ★ 2 |
| Last updated | July 29, 2026 |
| Repository | full-statck-skills/vue-skills ↗ |
What it does
Guidance for Vue Router v4 route configuration, nested routes, navigation guards and Composition API integration in Vue 3.
Files
When to use this skill
Use this skill whenever the user wants to:
- Set up routing in a Vue 3 application
- Configure routes, nested routes, and named routes
- Implement navigation guards (global, per-route, in-component)
- Use programmatic navigation with
router.push(),router.replace(), etc. - Handle dynamic route matching and route parameters
- Work with route meta fields and route records
- Implement lazy loading and code splitting for routes
- Use Vue Router with Composition API (
useRouter,useRoute) - Configure different history modes (hash, HTML5 history, memory)
- Handle scroll behavior and transitions
- Implement typed routes with TypeScript
- Migrate from Vue Router 3 to Vue Router 4
- Extend RouterLink component
- Handle navigation failures and errors
- Work with dynamic routing (adding/removing routes at runtime)
How to use this skill
This skill is organized to match the Vue Router official documentation structure (https://router.vuejs.org/guide/, https://router.vuejs.org/api/). When working with Vue Router:
1. Identify the topic from the user's request:
- Getting started/快速开始 →
examples/essentials/getting-started.md - Dynamic route matching/动态路由匹配 →
examples/essentials/dynamic-route-matching.md - Routes matching syntax/路由匹配语法 →
examples/essentials/routes-matching-syntax.md - Named routes/命名路由 →
examples/essentials/named-routes.md - Nested routes/嵌套路由 →
examples/essentials/nested-routes.md - Programmatic navigation/编程式导航 →
examples/essentials/programmatic-navigation.md - Named views/命名视图 →
examples/essentials/named-views.md - Redirect and alias/重定向和别名 →
examples/essentials/redirect-alias.md - Passing props to route components/向路由组件传递 props →
examples/essentials/passing-props.md - Different history modes/不同的历史模式 →
examples/essentials/different-history-modes.md - Navigation guards/导航守卫 →
examples/advanced/navigation-guards.md - Route meta fields/路由元信息 →
examples/advanced/route-meta-fields.md - Data fetching/数据获取 →
examples/advanced/data-fetching.md - Composition API/组合式 API →
examples/advanced/composition-api.md - RouterView slot/RouterView 插槽 →
examples/advanced/routerview-slot.md - Transitions/过渡效果 →
examples/advanced/transitions.md - Scroll behavior/滚动行为 →
examples/advanced/scroll-behavior.md - Lazy loading routes/懒加载路由 →
examples/advanced/lazy-loading-routes.md - Typed routes/类型化路由 →
examples/advanced/typed-routes.md - Extending RouterLink/扩展 RouterLink →
examples/advanced/extending-router-link.md - Navigation failures/导航失败 →
examples/advanced/navigation-failures.md - Dynamic routing/动态路由 →
examples/advanced/dynamic-routing.md
2. Load the appropriate example file from the examples/ directory:
Essentials (基础) - `examples/essentials/`:
examples/essentials/getting-started.md- Creating a router and basic setupexamples/essentials/dynamic-route-matching.md- Dynamic route matching with paramsexamples/essentials/routes-matching-syntax.md- Route matching syntax and patternsexamples/essentials/named-routes.md- Named routes and navigationexamples/essentials/nested-routes.md- Nested routes and RouterViewexamples/essentials/programmatic-navigation.md- Programmatic navigation with router methodsexamples/essentials/named-views.md- Named views and multiple RouterViewexamples/essentials/redirect-alias.md- Redirects and aliasesexamples/essentials/passing-props.md- Passing props to route componentsexamples/essentials/different-history-modes.md- Hash, HTML5 history, and memory modes
Advanced (高级) - `examples/advanced/`:
examples/advanced/navigation-guards.md- Global, per-route, and in-component guardsexamples/advanced/route-meta-fields.md- Route meta fields and custom dataexamples/advanced/data-fetching.md- Data fetching strategiesexamples/advanced/composition-api.md- UsinguseRouter()anduseRoute()with Composition APIexamples/advanced/routerview-slot.md- RouterView slot propsexamples/advanced/transitions.md- Route transitions and animationsexamples/advanced/scroll-behavior.md- Scroll behavior configurationexamples/advanced/lazy-loading-routes.md- Lazy loading routes and code splittingexamples/advanced/typed-routes.md- TypeScript typed routesexamples/advanced/extending-router-link.md- Extending RouterLink componentexamples/advanced/navigation-failures.md- Handling navigation failuresexamples/advanced/dynamic-routing.md- Adding and removing routes dynamically
3. Follow the specific instructions in that example file for syntax, structure, and best practices
Important Notes:
- All examples follow Vue Router 4 API
- Examples include both JavaScript and TypeScript versions where applicable
- Each example file includes key concepts, code examples, and key points
- Always check the example file for best practices and common patterns
4. Reference API documentation in the api/ directory when needed:
api/router.md- Router instance API (createRouter,addRoute,removeRoute, etc.)api/route-records.md- Route record types and propertiesapi/useRouter-useRoute.md- Composition API functions (useRouter,useRoute)api/navigation-helpers.md- Navigation helper functionsapi/router-link-router-view-components.md- RouterLink and RouterView componentsapi/history-modes-api.md- History mode APIsapi/error-and-failure-types.md- Error and failure types
5. Use templates from the templates/ directory:
templates/router-setup.md- Router setup templatestemplates/route-config.md- Route configuration templates
Examples and Templates
This skill includes detailed examples organized to match the Vue Router official documentation structure (https://router.vuejs.org/guide/, https://router.vuejs.org/api/). All examples are in the examples/ directory, organized by topic:
Essentials (基础) - examples/essentials/
examples/essentials/getting-started.md- Creating a router, installing Vue Router, and basic setupexamples/essentials/dynamic-route-matching.md- Dynamic route matching with params and queryexamples/essentials/routes-matching-syntax.md- Route matching syntax, catch-all routes, and regexexamples/essentials/named-routes.md- Named routes and navigation with namesexamples/essentials/nested-routes.md- Nested routes and nested RouterViewexamples/essentials/programmatic-navigation.md- Programmatic navigation withrouter.push(),router.replace(),router.go()examples/essentials/named-views.md- Named views and multiple RouterView componentsexamples/essentials/redirect-alias.md- Redirects and aliases configurationexamples/essentials/passing-props.md- Passing props to route componentsexamples/essentials/different-history-modes.md- Hash mode, HTML5 history mode, and memory mode
Advanced (高级) - examples/advanced/
examples/advanced/navigation-guards.md- Global guards, per-route guards, and in-component guardsexamples/advanced/route-meta-fields.md- Route meta fields and accessing meta in guardsexamples/advanced/data-fetching.md- Data fetching strategies (before navigation, after navigation)examples/advanced/composition-api.md- UsinguseRouter()anduseRoute()with Composition APIexamples/advanced/routerview-slot.md- RouterView slot props and custom renderingexamples/advanced/transitions.md- Route transitions and animationsexamples/advanced/scroll-behavior.md- Scroll behavior configurationexamples/advanced/lazy-loading-routes.md- Lazy loading routes and code splittingexamples/advanced/typed-routes.md- TypeScript typed routes and type safetyexamples/advanced/extending-router-link.md- Extending RouterLink componentexamples/advanced/navigation-failures.md- Handling navigation failures and errorsexamples/advanced/dynamic-routing.md- Adding and removing routes dynamically at runtime
Templates Directory (templates/)
templates/router-setup.md- Router setup templates for different scenariostemplates/route-config.md- Route configuration templates
To use examples:
- Identify the topic from the user's request
- Load the appropriate example file from the corresponding directory
- Follow the instructions, syntax, and best practices in that file
- Adapt the code examples to your specific use case
To use templates:
- Reference
templates/router-setup.mdfor router setup templates - Use
templates/route-config.mdfor route configuration templates - Adapt templates to your specific needs and coding style
API Reference
Detailed API documentation is available in the api/ directory, organized to match the official Vue Router API documentation structure:
Router API (api/router.md)
createRouter()- Creating a router instance- Router instance methods:
addRoute(),removeRoute(),hasRoute(),getRoutes(),push(),replace(),go(),back(),forward() - Router instance properties:
currentRoute,options
Route Records API (api/route-records.md)
- Route record types and properties
- Route configuration options
Composition API (api/useRouter-useRoute.md)
useRouter()- Access router instance in setupuseRoute()- Access current route in setup
Navigation Helpers (api/navigation-helpers.md)
- Navigation helper functions and utilities
Components API (api/router-link-router-view-components.md)
RouterLinkcomponent props and usageRouterViewcomponent props and usage
History Modes API (api/history-modes-api.md)
createWebHistory()- HTML5 history modecreateWebHashHistory()- Hash modecreateMemoryHistory()- Memory mode
Error and Failure Types (api/error-and-failure-types.md)
- Navigation failure types
- Error handling
To use API reference: 1. Identify the API you need help with 2. Load the corresponding API file from the api/ directory 3. Find the API signature, parameters, return type, and examples 4. Reference the linked example files for detailed usage patterns 5. All API files include links to relevant example files in the examples/ directory
Best Practices
1. Use named routes: Use named routes for better maintainability and refactoring 2. Lazy load routes: Use dynamic imports for route components to enable code splitting 3. Type safety: Use TypeScript with typed routes for better type safety 4. Navigation guards: Use navigation guards appropriately (global, per-route, in-component) 5. Route meta: Use route meta fields for custom data and permissions 6. History mode: Choose the appropriate history mode based on deployment environment 7. Scroll behavior: Configure scroll behavior for better UX 8. Error handling: Handle navigation failures gracefully
Resources
- Official Guide: https://router.vuejs.org/guide/
- API Reference: https://router.vuejs.org/api/
- Migration Guide: https://router.vuejs.org/guide/migration/
- GitHub Repository: https://github.com/vuejs/router
Keywords
Vue Router, router, routing, navigation, route, routes, nested routes, named routes, dynamic routes, route params, route query, navigation guards, route meta, programmatic navigation, RouterLink, RouterView, useRouter, useRoute, history mode, hash mode, HTML5 history, lazy loading, code splitting, typed routes, TypeScript, 路由, 导航, 路由守卫, 嵌套路由, 命名路由, 动态路由, 编程式导航, 懒加载, 类型化路由
能力边界
✅ 适用场景
- 当你需要使用此技能对应的技术栈时
- 当项目需要遵循最佳实践时
- 当需要快速上手或深入理解核心概念时
⚠️ 需要注意
- 复杂业务逻辑需要结合具体场景调整
- 性能优化需要根据实际数据量评估
❌ 不适用场景
- 不相关的技术栈或框架
- 需要完全自定义的特殊场景
常见陷阱 (Gotchas)
1. 版本兼容性:注意框架版本与依赖库的兼容性,不同版本 API 可能有差异 2. 配置文件格式:配置文件格式错误是最常见的问题,建议使用编辑器的语法检查 3. 环境变量:确保所有必要的环境变量已正确设置,敏感信息不要硬编码 4. 依赖冲突:多版本共存时注意依赖冲突,使用 lock 文件锁定版本 5. 性能陷阱:大数据量场景下注意性能优化,避免 N+1 查询等常见问题
使用流程
Step 1: 环境准备
确保开发环境已安装必要的依赖和工具。
Step 2: 配置初始化
根据项目需求进行基础配置。
Step 3: 核心功能使用
按照示例代码实现核心功能。
Step 4: 测试验证
运行测试确保功能正常。
Step 5: 部署上线
完成开发后进行部署和监控。
Composables | 组合式 API
官方文档: https://router.vuejs.org/api/#userouter
关键 API
useRouter()/useRoute()onBeforeRouteLeave()/onBeforeRouteUpdate()
示例
// useRouteInfo(): 读取当前路由信息
function useRouteInfo() {
const router = useRouter()
const route = useRoute()
return { router, route }
}History | 历史模式 API
官方文档: https://router.vuejs.org/api/#history
关键 API
createWebHistory()createWebHashHistory()createMemoryHistory()
示例
// createHistory(): 根据环境创建 History
function createHistory() {
return import.meta.env.SSR
? createMemoryHistory()
: createWebHistory()
}API Overview | API 概览
官方文档: https://router.vuejs.org/api/
使用方式
- 先定位 API 类别(Router、History、RouteRecord、RouteLocation、组件、组合式 API)
- 再查看对应文件的签名与示例
API 分类
- Router 实例与 RouterOptions
- History 模式(HTML5/Hash/Memory)
- RouteRecord 与 RouteLocation 类型
- RouterLink / RouterView 组件
- useRouter / useRoute / onBeforeRouteLeave / onBeforeRouteUpdate
- 导航失败与错误类型
Navigation Failures | 导航失败
官方文档: https://router.vuejs.org/api/#navigationfailure
关键 API
NavigationFailureTypeisNavigationFailure()
示例
// handleFailure(): 处理导航失败
async function handleFailure() {
const failure = await router.push('/dashboard')
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
console.warn('重复导航被忽略')
}
}RouteLocation | 路由位置类型
官方文档: https://router.vuejs.org/api/#routelocationraw
关键类型
RouteLocationRawRouteLocationNormalized
示例
// buildLocation(): 构建路由位置对象
function buildLocation(id: string): RouteLocationRaw {
return { name: 'User', params: { id } }
}RouteRecordRaw | 路由记录
官方文档: https://router.vuejs.org/api/#routerecordraw
关键字段
path/name/component/childrenredirect/alias/meta
示例
// buildRoutes(): 定义路由记录
function buildRoutes(): RouteRecordRaw[] {
return [
{
path: '/users/:id',
name: 'User',
component: () => import('@/views/User.vue'),
meta: { requiresAuth: true }
}
]
}RouterLink | 路由链接组件
官方文档: https://router.vuejs.org/api/#routerlink
常用属性
to/replace/customactive-class/exact-active-class
示例
<template>
<RouterLink :to="{ name: 'Home' }">Home</RouterLink>
</template>
<script setup lang="ts">
import { RouterLink } from 'vue-router'
</script>RouterOptions | 路由器配置
官方文档: https://router.vuejs.org/api/#routeroptions
关键字段
history:历史模式实例routes:路由记录数组scrollBehavior:滚动行为
示例
// buildRouterOptions(): 构建路由配置
function buildRouterOptions() {
return {
history: createWebHistory(import.meta.env.BASE_URL),
routes,
scrollBehavior(to, from, savedPosition) {
return savedPosition ?? { top: 0 }
}
}
}RouterView | 路由视图组件
官方文档: https://router.vuejs.org/api/#routerview
常用属性
nameroute
示例
<template>
<RouterView />
</template>
<script setup lang="ts">
import { RouterView } from 'vue-router'
</script>Router | 路由器实例
官方文档: https://router.vuejs.org/api/#router
关键 API
createRouter()router.push()/router.replace()/router.go()router.addRoute()/router.removeRoute()/router.hasRoute()/router.getRoutes()router.currentRoute
示例
// createAppRouter(): 创建路由器实例
export function createAppRouter() {
return createRouter({
history: createWebHistory(),
routes
})
}
// navigateToUser(): 编程式导航
function navigateToUser(id: string) {
return router.push({ name: 'User', params: { id } })
}Composition API | 组合式 API
官方文档: https://router.vuejs.org/guide/advanced/composition-api.html
Instructions
This example demonstrates how to use Vue Router with the Composition API in Vue 3.
Key Concepts
useRouter()- Access router instanceuseRoute()- Access current route- Using router in
setup()function - Reactive route properties
- Navigation with Composition API
Example: Basic Usage
<template>
<div>
<p>Current route: {{ route.path }}</p>
<button @click="goHome">Go Home</button>
</div>
</template>
<script setup>
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
function goHome() {
router.push('/')
}
</script>Example: Accessing Route Params
<template>
<div>
<h1>User {{ userId }}</h1>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
const route = useRoute()
const userId = computed(() => route.params.id)
</script>Example: Accessing Query and Hash
<template>
<div>
<p>Query: {{ route.query }}</p>
<p>Hash: {{ route.hash }}</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>Example: Navigation Methods
<template>
<div>
<button @click="pushRoute">Push</button>
<button @click="replaceRoute">Replace</button>
<button @click="goBack">Back</button>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function pushRoute() {
router.push('/home')
}
function replaceRoute() {
router.replace('/home')
}
function goBack() {
router.back()
}
</script>Example: Watching Route Changes
<template>
<div>User {{ userId }}</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
import { watch } from 'vue'
const route = useRoute()
watch(() => route.params.id, (newId, oldId) => {
console.log(`User changed from ${oldId} to ${newId}`)
// Fetch new user data
fetchUserData(newId)
})
</script>Example: Using Route Meta
<template>
<div>
<h1>{{ route.meta.title }}</h1>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>Example: Programmatic Navigation with Params
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function navigateToUser(id) {
router.push({
name: 'User',
params: { id }
})
}
function navigateWithQuery(query) {
router.push({
path: '/search',
query: { q: query }
})
}
</script>Example: TypeScript Support
<script setup lang="ts">
import { useRouter, useRoute } from 'vue-router'
import type { RouteLocationNormalized } from 'vue-router'
const router = useRouter()
const route: RouteLocationNormalized = useRoute()
const userId = computed(() => route.params.id as string)
</script>Key Points
useRouter()returns the router instanceuseRoute()returns the current route (reactive)- Route properties are reactive and update automatically
- Can use
watchto react to route changes - Works seamlessly with Composition API
- TypeScript support available
- No need to access
this.$routerorthis.$route
Data Fetching | 数据获取
官方文档: https://router.vuejs.org/guide/advanced/data-fetching.html
适用场景
- 进入路由前加载数据
- 路由参数变化时刷新数据
核心用法
// fetchUser(): 根据路由参数获取数据
async function fetchUser(id: string) {
return await api.getUser(id)
}
// beforeEnter(): 进入路由前加载数据
const routes = [
{
path: '/users/:id',
component: UserView,
beforeEnter: async (to) => {
to.meta.user = await fetchUser(String(to.params.id))
}
}
]关键点
- 在进入路由前或组件内触发数据请求
- 配合
watch(() => route.params)处理参数变化
Dynamic Routing | 动态路由
官方文档: https://router.vuejs.org/guide/advanced/dynamic-routing.html
适用场景
- 根据权限动态添加路由
- 运行时移除不需要的路由
核心用法
// addAdminRoutes(): 按权限添加路由
function addAdminRoutes() {
router.addRoute({
path: '/admin',
name: 'Admin',
component: () => import('@/views/Admin.vue')
})
}
// removeAdminRoutes(): 移除路由
function removeAdminRoutes() {
router.removeRoute('Admin')
}Extending RouterLink | 扩展 RouterLink
官方文档: https://router.vuejs.org/guide/advanced/extending-router-link.html
适用场景
- 自定义链接样式或行为
- 统一封装项目内导航
核心用法
import { defineComponent } from 'vue'
import { useLink } from 'vue-router'
// useCustomLink(): 封装 RouterLink 行为
export const useCustomLink = (props: any) => {
const link = useLink(props)
return link
}
// CustomLink: 自定义链接组件
export default defineComponent({
props: ['to'],
setup(props) {
return useCustomLink(props)
}
})Lazy Loading Routes | 懒加载路由
官方文档: https://router.vuejs.org/guide/advanced/lazy-loading.html
Instructions
This example demonstrates how to implement lazy loading for routes to enable code splitting and improve performance.
Key Concepts
- Dynamic imports with
import() - Code splitting
- Route-level code splitting
- Grouping routes for chunking
- Webpack chunk names
Example: Basic Lazy Loading
// router/index.js
const routes = [
{
path: '/',
component: () => import('../views/Home.vue')
},
{
path: '/about',
component: () => import('../views/About.vue')
}
]Example: Named Chunks
const routes = [
{
path: '/user/:id',
component: () => import(/* webpackChunkName: "user" */ '../views/User.vue')
}
]Example: Grouping Routes
const routes = [
{
path: '/user/:id',
component: () => import(/* webpackChunkName: "user-group" */ '../views/User.vue')
},
{
path: '/user/:id/posts',
component: () => import(/* webpackChunkName: "user-group" */ '../views/UserPosts.vue')
}
]Example: With Loading Component
<template>
<Suspense>
<template #default>
<RouterView />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>Example: Error Handling
const routes = [
{
path: '/user/:id',
component: () => import('../views/User.vue').catch(() => {
// Handle import error
return import('../views/Error.vue')
})
}
]Key Points
- Use dynamic
import()for lazy loading - Enables code splitting automatically
- Reduces initial bundle size
- Routes are loaded on-demand
- Can use webpack chunk names for grouping
- Works with Vite and other bundlers
Navigation Failures | 导航失败
官方文档: https://router.vuejs.org/guide/advanced/navigation-failures.html
适用场景
- 处理重复导航与导航被取消
- 统一错误提示与埋点
核心用法
import { isNavigationFailure, NavigationFailureType } from 'vue-router'
// handleNavigation(): 处理导航失败
async function handleNavigation() {
const failure = await router.push('/dashboard')
if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
console.warn('重复导航被忽略')
}
}Navigation Guards | 导航守卫
官方文档: https://router.vuejs.org/guide/advanced/navigation-guards.html
Instructions
This example demonstrates how to use navigation guards to control navigation and perform actions before/after route changes.
Key Concepts
- Global before guards (
beforeEach) - Global after guards (
afterEach) - Per-route guards (
beforeEnter) - In-component guards (
beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave) - Navigation guard arguments and return values
Example: Global Before Guard
// router/index.js
router.beforeEach((to, from, next) => {
// Check authentication
if (to.meta.requiresAuth && !isAuthenticated()) {
next({ name: 'Login' })
} else {
next()
}
})Example: Global After Guard
router.afterEach((to, from) => {
// Log page views
console.log(`Navigated from ${from.path} to ${to.path}`)
// Send analytics
analytics.track('page_view', {
path: to.path,
name: to.name
})
})Example: Per-Route Guard
const routes = [
{
path: '/dashboard',
component: Dashboard,
beforeEnter: (to, from, next) => {
if (isAuthenticated()) {
next()
} else {
next({ name: 'Login' })
}
}
}
]Example: In-Component Guards (Options API)
<template>
<div>User Profile</div>
</template>
<script>
export default {
beforeRouteEnter(to, from, next) {
// Called before the route is confirmed
// No access to `this` component instance
fetchUserData(to.params.id).then(() => {
next()
})
},
beforeRouteUpdate(to, from, next) {
// Called when the route changes but component is reused
// Has access to `this`
if (to.params.id !== from.params.id) {
this.fetchUserData(to.params.id)
}
next()
},
beforeRouteLeave(to, from, next) {
// Called when leaving the route
// Has access to `this`
if (this.hasUnsavedChanges) {
if (confirm('You have unsaved changes. Are you sure?')) {
next()
} else {
next(false)
}
} else {
next()
}
}
}
</script>Example: In-Component Guards (Composition API)
<template>
<div>User Profile</div>
</template>
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'
const hasUnsavedChanges = ref(false)
onBeforeRouteLeave((to, from) => {
if (hasUnsavedChanges.value) {
const answer = confirm('You have unsaved changes. Are you sure?')
if (!answer) return false
}
})
onBeforeRouteUpdate(async (to, from) => {
if (to.params.id !== from.params.id) {
await fetchUserData(to.params.id)
}
})
</script>Example: Navigation Guard with Async Operations
router.beforeEach(async (to, from, next) => {
if (to.meta.requiresAuth) {
try {
const user = await checkAuth()
if (user) {
next()
} else {
next({ name: 'Login' })
}
} catch (error) {
next({ name: 'Error' })
}
} else {
next()
}
})Example: Multiple Guards
// Guards execute in order
router.beforeEach((to, from, next) => {
console.log('Guard 1')
next()
})
router.beforeEach((to, from, next) => {
console.log('Guard 2')
next()
})Key Points
beforeEachandbeforeEntercan redirect or cancel navigationafterEachcannot affect navigationbeforeRouteEnterdoesn't have access to component instancebeforeRouteUpdateandbeforeRouteLeavehave access tothis- Guards can be async
- Multiple guards execute in order
- Use
next(false)to cancel navigation - Use
next('/path')ornext({ name: 'Route' })to redirect
Route Meta Fields | 路由元信息
官方文档: https://router.vuejs.org/guide/advanced/meta.html
Instructions
This example demonstrates how to use route meta fields to attach custom data to routes.
Key Concepts
- Defining meta fields in route configuration
- Accessing meta in components
- Using meta in navigation guards
- TypeScript support for meta
Example: Defining Meta Fields
const routes = [
{
path: '/dashboard',
component: Dashboard,
meta: {
requiresAuth: true,
title: 'Dashboard',
roles: ['admin', 'user']
}
},
{
path: '/admin',
component: Admin,
meta: {
requiresAuth: true,
requiresAdmin: true,
title: 'Admin Panel'
}
}
]Example: Accessing Meta in Components
<template>
<div>
<h1>{{ route.meta.title }}</h1>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>Example: Using Meta in Guards
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next({ name: 'Login' })
} else if (to.meta.requiresAdmin && !isAdmin()) {
next({ name: 'Forbidden' })
} else {
next()
}
})Example: TypeScript Meta Types
// router/index.ts
import 'vue-router'
declare module 'vue-router' {
interface RouteMeta {
requiresAuth?: boolean
requiresAdmin?: boolean
title?: string
roles?: string[]
}
}
const routes = [
{
path: '/dashboard',
meta: {
requiresAuth: true,
title: 'Dashboard'
}
}
]Key Points
- Meta fields are arbitrary data attached to routes
- Access via
route.metain components or guards - Useful for permissions, titles, breadcrumbs, etc.
- Can be typed with TypeScript
- Available in all route-related contexts
RouterView Slot | RouterView 插槽
官方文档: https://router.vuejs.org/guide/advanced/router-view-slot.html
适用场景
- 自定义路由视图渲染
- 控制过渡与缓存策略
核心用法
<template>
<RouterView v-slot="{ Component, route }">
<!-- renderKey(): 生成稳定的渲染 key -->
<component :is="Component" :key="renderKey(route)" />
</RouterView>
</template>
<script setup lang="ts">
import { RouterView } from 'vue-router'
// renderKey(): 根据路由生成 key
const renderKey = (route: any) => route.fullPath
</script>Scroll Behavior | 滚动行为
官方文档: https://router.vuejs.org/guide/advanced/scroll-behavior.html
Instructions
This example demonstrates how to configure scroll behavior when navigating between routes.
Key Concepts
- Configuring scroll behavior in router options
- Scroll to top on navigation
- Preserving scroll position
- Smooth scrolling
- Custom scroll behavior
Example: Basic Scroll Behavior
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
// Always scroll to top
return { top: 0 }
}
})Example: Preserve Scroll Position
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
}Example: Smooth Scrolling
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return {
top: 0,
behavior: 'smooth'
}
}
}Example: Scroll to Element
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: to.hash,
behavior: 'smooth'
}
}
return { top: 0 }
}Key Points
- Configure in router options
savedPositionis available when using browser back/forward- Can return position object or Promise
- Use
elto scroll to specific element - Use
behavior: 'smooth'for smooth scrolling
SSR | 服务端渲染
官方文档: https://router.vuejs.org/guide/advanced/ssr.html
适用场景
- SSR 应用路由初始化
- 为每个请求创建独立路由实例
核心用法
import { createMemoryHistory, createRouter } from 'vue-router'
// createSsrRouter(): 为 SSR 请求创建路由实例
export function createSsrRouter() {
return createRouter({
history: createMemoryHistory(),
routes
})
}Transitions | 过渡效果
官方文档: https://router.vuejs.org/guide/advanced/transitions.html
Instructions
This example demonstrates how to add transitions between route changes.
Key Concepts
- Wrapping RouterView with Transition
- Transition modes
- Per-route transitions
- Dynamic transitions
Example: Basic Transition
<template>
<RouterView v-slot="{ Component, route }">
<Transition name="fade" mode="out-in">
<component :is="Component" :key="route.path" />
</Transition>
</RouterView>
</template>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>Example: Slide Transition
<template>
<RouterView v-slot="{ Component, route }">
<Transition name="slide" mode="out-in">
<component :is="Component" :key="route.path" />
</Transition>
</RouterView>
</template>
<style>
.slide-enter-active,
.slide-leave-active {
transition: transform 0.3s;
}
.slide-enter-from {
transform: translateX(100%);
}
.slide-leave-to {
transform: translateX(-100%);
}
</style>Example: Per-Route Transition
<template>
<RouterView v-slot="{ Component, route }">
<Transition :name="route.meta.transition || 'fade'">
<component :is="Component" :key="route.path" />
</Transition>
</RouterView>
</template>Key Points
- Use Transition component with RouterView
- Use
mode="out-in"for smooth transitions - Key on route.path for proper transitions
- Can use route meta for per-route transitions
- CSS transitions or JavaScript hooks available
Typed Routes | 类型化路由
官方文档: https://router.vuejs.org/guide/advanced/typed-routes.html
Instructions
This example demonstrates how to use TypeScript with Vue Router for type-safe routing.
Key Concepts
- TypeScript route types
- Typed route names
- Typed route params
- Typed route meta
- Type-safe navigation
Example: Basic TypeScript Setup
// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/user/:id',
name: 'User',
component: () => import('../views/User.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default routerExample: Typed Route Names
// types/router.d.ts
import 'vue-router'
declare module 'vue-router' {
interface RouteNamedMap {
'Home': RouteRecordInfo<'Home', '/', Record<never, never>, Record<never, never>>
'User': RouteRecordInfo<'User', '/user/:id', { id: string }, Record<never, never>>
}
}Example: Typed Navigation
import { useRouter } from 'vue-router'
const router = useRouter()
// Type-safe navigation
router.push({ name: 'User', params: { id: '123' } })Example: Typed Route Params
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
// Type-safe params
const userId = route.params.id as string
</script>Key Points
- Use
RouteRecordRawfor route definitions - TypeScript provides type safety for routes
- Typed route names prevent typos
- Typed params ensure correct parameter types
- Better IDE autocomplete and error checking
Dynamic Route Matching | 动态路由匹配
官方文档: https://router.vuejs.org/guide/essentials/dynamic-matching.html
Instructions
This example demonstrates how to use dynamic route parameters and query strings in Vue Router.
Key Concepts
- Dynamic route parameters with
:param - Accessing route params with
$route.paramsoruseRoute() - Route query strings
- Multiple dynamic segments
- Optional parameters
Example: Basic Dynamic Route
// router/index.js
const routes = [
{
path: '/user/:id',
name: 'User',
component: User
}
]<!-- User.vue -->
<template>
<div>
<h1>User {{ $route.params.id }}</h1>
</div>
</template>Example: Multiple Dynamic Segments
const routes = [
{
path: '/user/:username/post/:postId',
name: 'UserPost',
component: UserPost
}
]<!-- UserPost.vue -->
<template>
<div>
<h1>User: {{ $route.params.username }}</h1>
<h2>Post: {{ $route.params.postId }}</h2>
</div>
</template>Example: Using Composition API
<!-- User.vue -->
<template>
<div>
<h1>User {{ route.params.id }}</h1>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>Example: Route Query Strings
// Navigation with query
router.push({ path: '/search', query: { q: 'vue' } })
// Results in: /search?q=vue<!-- Search.vue -->
<template>
<div>
<h1>Search: {{ $route.query.q }}</h1>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const searchQuery = route.query.q
</script>Example: Optional Parameters
const routes = [
{
path: '/user/:id?',
name: 'User',
component: User
}
]Example: Reacting to Route Changes
<!-- User.vue -->
<template>
<div>
<h1>User {{ userId }}</h1>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
import { computed, watch } from 'vue'
const route = useRoute()
const userId = computed(() => route.params.id)
// Watch for route changes
watch(() => route.params.id, (newId, oldId) => {
// Fetch new user data
console.log(`User changed from ${oldId} to ${newId}`)
})
</script>Key Points
- Dynamic segments start with
:(e.g.,:id) - Access params via
$route.params(Options API) oruseRoute().params(Composition API) - Query strings are accessed via
$route.queryoruseRoute().query - Use
watchto react to route parameter changes - Optional parameters use
?(e.g.,:id?)
Getting Started | 快速开始
官方文档: https://router.vuejs.org/guide/
Instructions
This example demonstrates how to create a Vue Router instance and set up basic routing in a Vue 3 application.
Key Concepts
- Installing Vue Router
- Creating a router instance with
createRouter() - Defining routes
- Registering the router with the Vue app
- Using
RouterLinkandRouterViewcomponents
Example: Installation
# Using npm
npm install vue-router@4
# Using yarn
yarn add vue-router@4
# Using pnpm
pnpm add vue-router@4Example: Creating a Router
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default routerExample: Registering Router with App
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')Example: Using RouterLink and RouterView
<!-- App.vue -->
<template>
<div id="app">
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
<RouterView />
</div>
</template>
<script setup>
import { RouterLink, RouterView } from 'vue-router'
</script>Example: TypeScript Setup
// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default routerKey Points
- Use
createRouter()to create a router instance (replacesnew VueRouter()from Vue Router 3) - Use
createWebHistory()for HTML5 history mode (replacesmode: 'history') - Routes are defined as an array of route objects
- Register the router with
app.use(router) RouterLinkandRouterVieware components that need to be imported- In Vue Router 4, components are automatically available globally when using
app.use(router), but you can also import them explicitly
Different History Modes | 不同的历史模式
官方文档: https://router.vuejs.org/guide/essentials/history-mode.html
Instructions
This example demonstrates the different history modes available in Vue Router: hash mode, HTML5 history mode, and memory mode.
Key Concepts
- Hash mode (
createWebHashHistory) - HTML5 history mode (
createWebHistory) - Memory mode (
createMemoryHistory) - When to use each mode
- Server configuration for HTML5 history mode
Example: Hash Mode
// router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes
})
// URLs will look like: http://example.com/#/homeExample: HTML5 History Mode
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes
})
// URLs will look like: http://example.com/homeExample: HTML5 History with Base Path
const router = createRouter({
history: createWebHistory('/my-app/'),
routes
})
// URLs will look like: http://example.com/my-app/homeExample: Memory Mode
// router/index.js
import { createRouter, createMemoryHistory } from 'vue-router'
const router = createRouter({
history: createMemoryHistory(),
routes
})
// Used in SSR or testing environmentsExample: Server Configuration for HTML5 History
Nginx:
location / {
try_files $uri $uri/ /index.html;
}Apache (.htaccess):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>Express:
const express = require('express')
const path = require('path')
const app = express()
app.use(express.static(path.join(__dirname, 'dist')))
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})Example: Choosing the Right Mode
// Development: Use hash mode for simplicity
const router = createRouter({
history: process.env.NODE_ENV === 'development'
? createWebHashHistory()
: createWebHistory(),
routes
})Key Points
- Hash mode: Works without server configuration, URLs have
#, good for simple deployments - HTML5 history mode: Clean URLs, requires server configuration, better for production
- Memory mode: No URL changes, used in SSR and testing
- Hash mode is easier to deploy but has less clean URLs
- HTML5 history mode requires server fallback to
index.html - Choose based on deployment environment and requirements
Named Routes | 命名路由
官方文档: https://router.vuejs.org/guide/essentials/named-routes.html
Instructions
This example demonstrates how to use named routes for navigation and route configuration.
Key Concepts
- Defining named routes with
nameproperty - Navigating to named routes
- Benefits of named routes
- Using named routes with params and query
Example: Defining Named Routes
// router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/user/:id',
name: 'User',
component: User
},
{
path: '/user/:id/posts/:postId',
name: 'UserPost',
component: UserPost
}
]Example: Navigating to Named Routes
// Using router.push()
router.push({ name: 'Home' })
router.push({ name: 'User', params: { id: '123' } })
router.push({ name: 'UserPost', params: { id: '123', postId: '456' } })
// Using RouterLink
<RouterLink :to="{ name: 'Home' }">Home</RouterLink>
<RouterLink :to="{ name: 'User', params: { id: '123' } }">User</RouterLink>Example: Named Routes with Query
router.push({
name: 'User',
params: { id: '123' },
query: { tab: 'profile' }
})Example: Using in Components
<template>
<div>
<RouterLink :to="{ name: 'Home' }">Home</RouterLink>
<RouterLink :to="{ name: 'User', params: { id: userId } }">
User Profile
</RouterLink>
<button @click="goToUser">Go to User</button>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const userId = '123'
function goToUser() {
router.push({ name: 'User', params: { id: userId } })
}
</script>Example: Benefits of Named Routes
// Without named routes (fragile - breaks if path changes)
router.push('/user/123')
// With named routes (robust - path can change, name stays the same)
router.push({ name: 'User', params: { id: '123' } })Example: TypeScript with Named Routes
// router/index.ts
import { RouteRecordRaw } from 'vue-router'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/user/:id',
name: 'User',
component: () => import('../views/User.vue')
}
]
export default routesKey Points
- Use
nameproperty to define named routes - Named routes make navigation more maintainable
- Paths can change without breaking navigation code
- Can combine with params and query
- Better for refactoring and large applications
- TypeScript support for typed route names
Named Views | 命名视图
官方文档: https://router.vuejs.org/guide/essentials/named-views.html
Instructions
This example demonstrates how to use named views to display multiple RouterView components simultaneously.
Key Concepts
- Named views with
componentsproperty - Multiple RouterView components
- Default view
- Using named views with nested routes
Example: Basic Named Views
// router/index.js
const routes = [
{
path: '/settings',
components: {
default: SettingsMain,
sidebar: SettingsSidebar,
header: SettingsHeader
}
}
]<!-- App.vue -->
<template>
<div>
<RouterView name="header" />
<div class="container">
<RouterView name="sidebar" />
<RouterView />
</div>
</div>
</template>Example: Named Views with Nested Routes
const routes = [
{
path: '/user/:id',
component: UserLayout,
children: [
{
path: '',
components: {
default: UserProfile,
sidebar: UserSidebar
}
},
{
path: 'posts',
components: {
default: UserPosts,
sidebar: UserPostsSidebar
}
}
]
}
]Example: Using in Components
<!-- UserLayout.vue -->
<template>
<div class="user-layout">
<RouterView name="sidebar" />
<main>
<RouterView />
</main>
</div>
</template>Example: Navigation to Named Views
// Navigation doesn't change, router handles which views to show
router.push('/settings')Key Points
- Use
components(plural) instead ofcomponentfor named views - Default view uses
defaultkey - Each RouterView needs a
nameprop matching the component key - Named views allow multiple components per route
- Useful for complex layouts with sidebars, headers, etc.
Nested Routes | 嵌套路由
官方文档: https://router.vuejs.org/guide/essentials/nested-routes.html
Instructions
This example demonstrates how to create nested routes with child routes and nested RouterView components.
Key Concepts
- Nested routes with
childrenproperty - Nested RouterView components
- Relative paths in nested routes
- Empty path for nested index routes
Example: Basic Nested Routes
// router/index.js
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
// UserProfile will be rendered inside User's <router-view>
// when /user/:id/profile is matched
path: 'profile',
component: UserProfile
},
{
// UserPosts will be rendered inside User's <router-view>
// when /user/:id/posts is matched
path: 'posts',
component: UserPosts
}
]
}
]<!-- User.vue -->
<template>
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view />
</div>
</template>Example: Nested Index Route
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
// Empty path for nested index route
path: '',
component: UserHome
},
{
path: 'profile',
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
]
}
]Example: Absolute Paths in Nested Routes
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
// Relative path (default)
path: 'profile',
component: UserProfile
},
{
// Absolute path (starts with /)
path: '/settings',
component: Settings
}
]
}
]Example: Multiple Levels of Nesting
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
path: 'posts',
component: UserPosts,
children: [
{
path: ':postId',
component: PostDetail
}
]
}
]
}
]Example: Using Composition API
<!-- User.vue -->
<template>
<div class="user">
<h2>User {{ route.params.id }}</h2>
<RouterView />
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
import { RouterView } from 'vue-router'
const route = useRoute()
</script>Key Points
- Use
childrenproperty to define nested routes - Nested routes require a
RouterViewin the parent component - Child route paths are relative to the parent by default
- Use empty path
''for nested index routes - Absolute paths (starting with
/) ignore parent path - Can nest multiple levels deep
Passing Props to Route Components | 向路由组件传递 Props
官方文档: https://router.vuejs.org/guide/essentials/passing-props.html
Instructions
This example demonstrates how to pass props to route components instead of using $route.params.
Key Concepts
- Boolean mode for props
- Object mode for props
- Function mode for props
- Accessing route params as props
Example: Boolean Mode
const routes = [
{
path: '/user/:id',
component: User,
props: true
}
]<!-- User.vue -->
<template>
<div>User {{ id }}</div>
</template>
<script setup>
defineProps({
id: String
})
</script>Example: Object Mode
const routes = [
{
path: '/user/:id',
component: User,
props: {
id: 'default-id',
showDetails: true
}
}
]<!-- User.vue -->
<template>
<div>
<p>User {{ id }}</p>
<div v-if="showDetails">Details...</div>
</div>
</template>
<script setup>
defineProps({
id: String,
showDetails: Boolean
})
</script>Example: Function Mode
const routes = [
{
path: '/user/:id',
component: User,
props: (route) => ({
id: route.params.id,
query: route.query,
hash: route.hash
})
}
]<!-- User.vue -->
<template>
<div>
<p>User {{ id }}</p>
<p>Query: {{ query }}</p>
</div>
</template>
<script setup>
defineProps({
id: String,
query: Object,
hash: String
})
</script>Example: Multiple Props
const routes = [
{
path: '/user/:id/posts/:postId',
component: UserPost,
props: true
}
]<!-- UserPost.vue -->
<template>
<div>
<p>User {{ id }}</p>
<p>Post {{ postId }}</p>
</div>
</template>
<script setup>
defineProps({
id: String,
postId: String
})
</script>Example: With Named Views
const routes = [
{
path: '/user/:id',
components: {
default: User,
sidebar: UserSidebar
},
props: {
default: true,
sidebar: false
}
}
]Key Points
props: truepasses route params as props- Object mode passes static props
- Function mode allows custom prop mapping
- Makes components more reusable and testable
- Components don't need to know about routing
- Can use different prop modes for different named views
Programmatic Navigation | 编程式导航
官方文档: https://router.vuejs.org/guide/essentials/navigation.html
Instructions
This example demonstrates how to navigate programmatically using the router instance methods.
Key Concepts
router.push()- Navigate to a new routerouter.replace()- Replace current routerouter.go()- Navigate through historyrouter.back()- Go back in historyrouter.forward()- Go forward in history- Using router in Options API and Composition API
Example: router.push()
// String path
router.push('/home')
// Object with path
router.push({ path: '/home' })
// Named route
router.push({ name: 'Home' })
// With params
router.push({ name: 'User', params: { id: '123' } })
// With query
router.push({ path: '/search', query: { q: 'vue' } })
// With hash
router.push({ path: '/home', hash: '#section' })Example: router.replace()
// Replace current route (doesn't add to history)
router.replace('/home')
router.replace({ name: 'Home' })Example: router.go()
// Go forward 1 step
router.go(1)
// Go back 1 step
router.go(-1)
// Go back 3 steps
router.go(-3)Example: router.back() and router.forward()
// Go back (equivalent to router.go(-1))
router.back()
// Go forward (equivalent to router.go(1))
router.forward()Example: Using in Options API
<template>
<button @click="goToHome">Go Home</button>
<button @click="goToUser">Go to User</button>
</template>
<script>
export default {
methods: {
goToHome() {
this.$router.push('/home')
},
goToUser() {
this.$router.push({ name: 'User', params: { id: '123' } })
}
}
}
</script>Example: Using in Composition API
<template>
<button @click="goToHome">Go Home</button>
<button @click="goToUser">Go to User</button>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function goToHome() {
router.push('/home')
}
function goToUser() {
router.push({ name: 'User', params: { id: '123' } })
}
</script>Example: Navigation with Promise
// router.push() returns a Promise
router.push('/home')
.then(() => {
console.log('Navigation successful')
})
.catch((err) => {
if (err.name === 'NavigationDuplicated') {
// Handle duplicate navigation
}
})Example: Conditional Navigation
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
async function navigateWithCheck() {
try {
await router.push('/protected')
} catch (err) {
if (err.name === 'NavigationAborted') {
console.log('Navigation was aborted')
}
}
}
</script>Key Points
router.push()adds a new entry to historyrouter.replace()replaces current entry (no history)router.go(n)navigates n steps in historyrouter.back()androuter.forward()are convenience methods- Navigation methods return Promises
- Can use string paths or route objects
- Use
useRouter()in Composition API,$routerin Options API
Redirect and Alias | 重定向和别名
官方文档: https://router.vuejs.org/guide/essentials/redirect-and-alias.html
Instructions
This example demonstrates how to use redirects and aliases in Vue Router.
Key Concepts
- Redirects with
redirectproperty - Aliases with
aliasproperty - Named redirects
- Function redirects
- Multiple aliases
Example: Basic Redirect
const routes = [
{
path: '/home',
redirect: '/'
},
{
path: '/old-path',
redirect: '/new-path'
}
]Example: Named Route Redirect
const routes = [
{
path: '/home',
redirect: { name: 'Home' }
}
]Example: Function Redirect
const routes = [
{
path: '/user/:id',
redirect: (to) => {
// Redirect to a different path based on route params
return { path: `/profile/${to.params.id}` }
}
}
]Example: Alias
const routes = [
{
path: '/',
component: Home,
alias: '/home'
},
{
path: '/user/:id',
component: User,
alias: '/u/:id'
}
]Example: Multiple Aliases
const routes = [
{
path: '/',
component: Home,
alias: ['/home', '/index', '/main']
}
]Example: Alias with Nested Routes
const routes = [
{
path: '/user/:id',
component: User,
alias: '/u/:id',
children: [
{
path: 'profile',
alias: ['profile', 'p'],
component: UserProfile
}
]
}
]Key Points
- Redirects navigate to a different route
- Aliases allow multiple paths to render the same component
- Redirects change the URL, aliases keep the original URL
- Can use string paths, named routes, or functions for redirects
- Aliases can be a string or array of strings
- Useful for maintaining backward compatibility and SEO
Routes Matching Syntax | 路由匹配语法
官方文档: https://router.vuejs.org/guide/essentials/route-matching-syntax.html
Instructions
This example demonstrates advanced route matching patterns including catch-all routes, regex patterns, and optional parameters.
Key Concepts
- Catch-all routes (
*) - Regex patterns in route paths
- Optional parameters
- Multiple parameters
- Route matching priority
Example: Catch-All Routes
// Match all routes
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
}
// Match all routes under a prefix
{
path: '/user/:pathMatch(.*)*',
name: 'UserCatchAll',
component: UserCatchAll
}Example: Regex Patterns
// Only match numeric IDs
{
path: '/user/:id(\\d+)',
component: User
}
// Match specific pattern
{
path: '/post/:year(\\d{4})/:month(\\d{2})',
component: Post
}
// Multiple patterns
{
path: '/:type(article|post)/:id',
component: Content
}Example: Optional Parameters
// Optional parameter
{
path: '/user/:id?',
component: User
}
// Optional with default
{
path: '/user/:id?',
component: User,
props: (route) => ({ id: route.params.id || 'default' })
}Example: Multiple Parameters
{
path: '/user/:username/post/:postId',
component: UserPost
}Example: Route Matching Priority
const routes = [
// More specific routes first
{
path: '/user/:id/posts',
component: UserPosts
},
{
path: '/user/:id',
component: User
},
// Catch-all last
{
path: '/:pathMatch(.*)*',
component: NotFound
}
]Example: Using Regex in Components
<template>
<div>
<p>User ID: {{ $route.params.id }}</p>
<p>Year: {{ $route.params.year }}</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// route.params.id will only be set if it matches \d+
// route.params.year will only be set if it matches \d{4}
</script>Key Points
- Use
:pathMatch(.*)*for catch-all routes - Regex patterns use
:param(regex)syntax - Optional parameters use
? - More specific routes should be defined before catch-all routes
- Regex patterns must match the entire segment
- Use parentheses for capturing groups in regex
Vue Router 概览 | Overview
官方文档: https://router.vuejs.org/
适用场景
- 了解 Vue Router 4 的核心能力与定位
- 确认 Vue 3 应用的路由选型与能力边界
核心要点
- Vue 3 官方路由方案
- 支持历史模式与哈希模式
- 支持导航守卫、懒加载、路由元信息与过渡
快速示例
// createRouter(): 创建路由器实例
const router = createRouter({
history: createWebHistory(),
routes: []
})Installation | 安装
官方文档: https://router.vuejs.org/guide/installation.html
适用场景
- 新项目集成 Vue Router 4
- 升级到 Vue Router 4
安装
npm install vue-router@4基础初始化
// createRouter(): 创建路由器实例
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
// installRouter(): 将路由器注册到应用
app.use(router)Migration | 迁移指南
官方文档: https://router.vuejs.org/guide/migration/
适用场景
- 从 Vue Router 3 迁移到 Vue Router 4
关键迁移点
new VueRouter()→createRouter()mode: 'history'→createWebHistory()base→createWebHistory(base)- 组件与 API 接口名称变更
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Route Configuration Templates | 路由配置模板
Basic Route
{
path: '/home',
name: 'Home',
component: Home
}Route with Params
{
path: '/user/:id',
name: 'User',
component: User
}Nested Route
{
path: '/user/:id',
component: UserLayout,
children: [
{
path: 'profile',
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
]
}Route with Meta
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
meta: {
requiresAuth: true,
title: 'Dashboard'
}
}Route with Guard
{
path: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
if (isAdmin()) {
next()
} else {
next('/login')
}
}
}Route with Redirect
{
path: '/home',
redirect: '/'
}Route with Alias
{
path: '/',
component: Home,
alias: '/home'
}Lazy Loaded Route
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}Router Setup Templates | 路由器设置模板
Basic Router Setup
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default routerRouter with TypeScript
// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Home from '../views/Home.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: Home
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default routerRouter with Hash Mode
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes
})Router with Navigation Guards
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes
})
router.beforeEach((to, from, next) => {
// Guard logic
next()
})
export default routerRouter with Lazy Loading
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]