VueRouter
[TOC]
索引
HTML5
History
- history.length:
number
,只读
,返回一个表示会话历史中的条目数量的整数,包括当前加载的页面。 - history.state:
State
,用于访问/操作浏览器历史记录中的状态对象。主要用于SPA中的导航操作。 - history.back():
()
,用于让浏览器回到历史记录中的前一个页面。可理解为模拟用户点击浏览器的“后退”按钮。 - history.forward():
()
,用于让浏览器前进到历史记录中的下一个页面。可理解为模拟用户点击浏览器的“前进”按钮。 - history.go():
(delta)
,用于在浏览器历史记录栈中进行前进或后退操作。 - history.pushState():
(state,title?,url?)
,用于将一个新的历史记录条目添加到浏览器的历史记录栈中,而不会刷新页面。 - history.replaceState():
(state,title?,url?)
,用于替换当前浏览器历史记录中的条目。 - onpopstate:
(event)=>void
,是一个浏览器的事件监听器,用于监听浏览器历史记录的变化。
VueRouter
组件
- <router-link>:
to replace? custom? active-class? exact-active-class? v-slot?
,是 Vue Router 的导航组件,用于在SPA中生成可点击的路由链接,默认渲染为a标签。核心作用是实现无刷新页面切换,并自动处理路由激活状态。 - <router-view>:
name?,v-slot?,
,是 Vue Router 的核心组件,用于在SPA中渲染当前路由匹配的组件。它相当于一个动态占位符,根据路由规则切换显示内容。
Router
创建router:
- createRouter():
({history,routes,scrollBehavior?,...})
,是 VueRouter4 中用于 创建路由实例 的核心函数。替代了 VueRouter3 的 new VueRouter()。 - createWebHashHistory():
(base?)
,用于创建基于 哈希模式(Hash Mode) 的路由历史记录。 - createWebHistory():
(base?)
,用于创建基于 HTML5 History API 的路由历史记录,也称为“历史模式”。 - createMemoryHistory():
()
,用于创建一个基于 内存 的路由历史记录,也称为“抽象模式”。 - useRouter():
()
,用于在组件中访问全局的 路由器实例(Router Instance),从而实现编程式导航和路由管理。
动态路由:
- router.addRoute():
(parentName?,route)
,是 Vue Router 提供的动态路由管理方法,允许在运行时向路由器实例添加新的路由规则。适用于需要根据用户权限、功能模块懒加载等场景动态扩展路由表的情况。 - router.removeRoute():
(name)
,是 Vue Router 提供的动态路由管理方法,用于在运行时通过路由名称或addRoute()返回的移除函数来删除路由。已注册的路由规则。适用于需要根据用户权限、模块卸载等场景动态调整路由表的场景。 - router.hasRoute():
(name)
,用于检查指定名称的路由是否已注册到路由器实例中。 - router.getRoutes():
()
,是 Vue Router 4 提供的方法,用于获取当前路由器实例中所有已注册的路由记录的完整列表。
导航守卫:
- router.beforeEach():
(guard)
,全局前置导航守卫,用于在每次路由跳转前执行自定义逻辑,如权限校验、数据预加载等。 - router.afterEach():
(guard)
,全局后置守卫,用于注册一个在 导航完成之后 执行的钩子函数。它不会改变导航结果,常用于执行与导航结果无关的后续处理操作,如埋点统计、页面标题更新等。 - router.beforeResolve():
()
,全局解析守卫,用于注册一个在 导航被确认之前 执行的钩子函数。
路由导航:
- router.push():
(to)
,核心导航方法,用于 编程式导航到新路由,支持多种参数形式。 - router.replace():
(to)
,编程式导航方法,用于 替换当前浏览器历史记录中的路由,不会新增历史条目。适用于需要隐藏当前导航记录的场景,如登录后跳转,不希望用户通过返回按钮回到登录页。 - router.back():
()
,导航方法,用于 返回浏览器历史记录中的上一页,相当于用户点击浏览器的后退按钮。简化了编程式导航中的后退操作。 - router.go():
(n)
,全局导航方法,用于在 浏览器历史记录栈 中前进或后退指定的步数。行为类似于浏览器的前进/后退按钮。
路由属性:
- router.currentRoute:
RouteLocationNormalized
,只读
,响应式
,用于获取当前激活路由的详细信息。 - router.resolve():
(location)
,用于手动解析路由配置,返回目标路由的标准化信息。适用于需要获取路由路径或匹配的组件等场景。 - router.options:
RouterOptions
,只读
,用于访问创建路由实例时传入的 全局配置对象。它包含路由初始化时的所有原始配置参数,适用于调试或动态读取全局路由配置的场景。
SSR:
- router.isReady():
()
,是 Vue Router4 引入的 异步方法,用于检查路由是否已完成初始导航,即首次路由解析。可确保在路由完全准备就绪后再执行客户端激活或异步数据加载操作。
错误处理:
- router.onError():
(handler)
,全局错误处理钩子,用于捕获在 导航过程中发生的异常或失败,如异步组件加载失败、导航被中止等。
Route
- useRoute():
()
,用于在组件中访问当前路由的响应式信息。 - route.path:
string
,只读
,响应式
,当前路由的路径字符串,用于获取或监听路由的路径部分,不含查询参数和哈希。 - route.fullPath:
string
,只读
,响应式
,用于获取当前路由的 完整路径,包含路径、查询参数和哈希。 - route.meta:
Record<string, unknown>
,响应式
,用于获取当前路由的元数据。 - route.name:
string| symbol| undefined
,只读
,用于获取当前路由的 名称,该名称在路由配置中定义。允许通过名称而非路径进行导航和逻辑处理。 - route.params:
Record<string, string|string[]>
,只读
,响应式
,用于获取当前路由的 动态路径参数,适用于从 URL 中提取动态部分。 - route.query:
Record<string, string|string[]>
,只读
,响应式
,用于获取当前路由的 查询参数。 - route.hash:
string
,只读
,响应式
,用于获取当前路由的 哈希值。常用于页面内锚点导航或状态标记。 - route.matched:
RouteRecordNormalized[]
,只读
,响应式
,返回一个包含 当前路由匹配的所有嵌套路由记录 的数组。适用于访问嵌套路由的元数据、路径等信息。
HTML5
History
length
history.length:number
,只读
,返回一个表示会话历史中的条目数量的整数,包括当前加载的页面。
state
history.state:State
,用于访问/操作浏览器历史记录中的状态对象。主要用于SPA中的导航操作。
- 返回:
- state:
State | null
,返回当前页面的状态对象。如果没有则返回null。
back()
history.back():()
,用于让浏览器回到历史记录中的前一个页面。可理解为模拟用户点击浏览器的“后退”按钮。
forward()
history.forward():()
,用于让浏览器前进到历史记录中的下一个页面。可理解为模拟用户点击浏览器的“前进”按钮。
go()
history.go():(delta)
,用于在浏览器历史记录栈中进行前进或后退操作。
- delta:
number
,表示在浏览器历史记录栈中的偏移量。正数
:浏览器会前进delta个页面。负数
:浏览器会后退delta个页面。0
:浏览器会刷新当前页面。超出范围
:超出历史栈的范围,浏览器不会做任何跳转,页面保持不变。
pushState()
history.pushState():(state,title?,url?)
,用于将一个新的历史记录条目添加到浏览器的历史记录栈中,而不会刷新页面。
state:
object
,包含有关该历史条目的信息的对象。title?:
string
,新的历史记录条目的标题。很少用到,常设为""
。url?:
string
,新的历史记录条目的 URL。必须是同一域名下的有效路径。示例:
- 基本用法
js// state 对象包含当前视图的信息 const state = { page: 1 }; const title = ""; // 通常是空字符串 const url = "/page1"; // 将新的历史记录条目添加到浏览器历史记录栈 history.pushState(state, title, url);
- 结合popstate 事件
js// 监听 popstate 事件 window.addEventListener("popstate", function(event) { console.log("State changed:", event.state); // 根据新的 state 进行页面更新 updatePageView(event.state.section); }); // 通过 pushState 改变历史记录 history.pushState({ section: "home" }, "", "/home"); // 模拟用户点击浏览器的后退按钮 history.back();
replaceState()
history.replaceState():(state,title?,url?)
,用于替换当前浏览器历史记录中的条目。
state:
object
,包含有关该历史条目的信息的对象。title?:
string
,新的历史记录条目的标题。很少用到,常设为""
。url?:
string
,新的历史记录条目的 URL。必须是同一域名下的有效路径。特性:
- 对比pushState():
- pushState()会添加新的历史记录条目,会增加一个新的条目。
- replaceState()会替换当前历史记录条目,不会改变历史栈的长度。
- 对比pushState():
示例:
- 替换当前历史记录的URL
js// 当前 URL 是 "/page1",我们想将它替换为 "/page2" const state = { page: 2 }; const title = ""; const url = "/page2"; // 替换当前的历史记录条目 history.replaceState(state, title, url);
- 结合popstate 事件
js// 监听 popstate 事件 window.addEventListener("popstate", function(event) { console.log("State changed:", event.state); // 根据新的 state 进行页面更新 updatePageView(event.state.section); }); // 替换历史记录 history.replaceState({ section: "home" }, "", "/home");
onpopstate
onpopstate:(event)=>void
,是一个浏览器的事件监听器,用于监听浏览器历史记录的变化。
- event:
{type,target,state}
,事件触发时传递的event对象。- state:
object
,与当前历史条目相关联的状态对象。
- state:
- 语法:
- 触发条件:当用户通过浏览器的“后退”/“前进”按钮导航,或通过 pushState()/replaceState() 方法修改历史记录时触发。
VueRouter
组件
<router-link>
<router-link>:to replace? custom? active-class? exact-active-class? v-slot?
,是 Vue Router 的导航组件,用于在SPA中生成可点击的路由链接,默认渲染为a标签。核心作用是实现无刷新页面切换,并自动处理路由激活状态。
to:
string|object
,指定目标路由的路径或路由对象。replace?:
boolean
,默认:false
,导航时替换当前历史记录。custom?:
boolean
,默认:false
,禁用默认a标签渲染,完全自定义内容,需手动实现路由跳转。active-class?:
string
,默认:router-link-active
,当目标路由是当前路由的子路径时激活 CSS 类名。exact-active-class?:
string
,默认:router-link-exact-active
,仅当目标路由与当前路由完全匹配时激活 CSS 类名。v-slot?:
{href?,route?,navigate?,isActive?,isExactActive?}
,通过 v-slot 可完全自定义链接内容和行为。用于替代vue-router3的tag属性。- href?:
string
,解析后的 URL,可用于原生a标签。 - route?:
object
,解析后的规范化路由对象。 - navigate?:
function
,触发导航的函数。 - isActive?:
boolean
,是否匹配当前路由。 - isExactActive?:
boolean
,是否严格匹配当前路由。
- href?:
语法:
参数to的类型:
- 字符串形式:
html<router-link to="/home">首页</router-link>
- 对象形式:动态路径或带参数。
html<router-link :to="{ path: '/user', query: { id: 1 } }">用户</router-link> <!-- 结果:/user?id=1 --> <router-link :to="{ name: 'profile', params: { username: 'alice' } }">个人资料</router-link> <!-- 结果:/profile/alice -->
参数v-slot:完全自定义链接内容和行为。
html<router-link to="/dashboard" v-slot="{ href, isActive }"> <a :href="href" :class="{ active: isActive }">控制台</a> </router-link>
路由激活状态:
html<!-- 当前路由为 /user/profile --> <router-link to="/user">用户中心</router-link> <!-- 激活类:router-link-active --> <router-link to="/user/profile">个人资料</router-link> <!-- 激活类:router-link-active + router-link-exact-active -->
常见用途:
基本导航:
html<router-link to="/">首页</router-link> <router-link :to="{ name: 'user', params: { id: 1 } }">用户 1</router-link>
带查询参数:
html<router-link :to="{ path: '/search', query: { q: 'vue' } }">搜索 Vue</router-link> <!-- 结果:/search?q=vue -->
自定义激活样式:
html<router-link to="/contact" active-class="active-link" exact-active-class="exact-active-link" > 联系我们 </router-link>
动态路径与参数:
html<!-- /posts/123 --> <router-link :to="`/posts/${postId}`">文章详情</router-link> <!-- /product/123?from=home --> <router-link :to="{ name: 'product', params: { id: product.id }, query: { from: 'home' } }"> {{ product.name }} </router-link>
导航守卫与事件:@
html<router-link to="/checkout" @click.native.prevent="handleClick" :event="isLoggedIn ? 'click' : ''" > 结算 </router-link>
注意事项:
- 避免在to中混用path和name:优先使用 name 以解耦路径。
- 动态参数需事先占位:使用 params 时,目标路由必须定义对应的参数占位符,如
/user/:id
。 - 慎用replace:替换历史记录后用户无法通过浏览器后退按钮返回。
- 性能优化:频繁变化的动态路由可结合
<keep-alive>
缓存组件状态。
<router-view>
<router-view>:name?,v-slot?,
,是 Vue Router 的核心组件,用于在SPA中渲染当前路由匹配的组件。它相当于一个动态占位符,根据路由规则切换显示内容。
name?:
string
,支持多视图渲染,需在路由配置中定义 components 对象。v-slot?:
{Component}
,暴露一个插槽,用来渲染路由组件。用于替代vue-router3的tag属性。语法:
渲染规则:
- 根据当前路由路径,自动匹配并渲染路由配置中对应的组件。
- 支持嵌套路由,通过层级 router-view 实现父子组件嵌套渲染。
命名视图:通过 name 属性支持多视图渲染,需在路由配置中定义 components 对象。
- 1、布局组件中定义多个命名视图
html<template> <div> <router-view name="header"></router-view> <router-view></router-view> <!-- 默认 name: default --> <router-view name="footer"></router-view> </div> </template>
- 2、路由配置
jsconst routes = [ { path: '/', components: { default: Home, // 默认视图渲染 Home 组件 header: Header, // 命名视图 header 渲染 Header 组件 footer: Footer // 命名视图 footer 渲染 Footer 组件 } } ];
嵌套路由:通过嵌套 router-view 实现多层组件结构。
- 1、路由配置
jsconst routes = [ { path: '/user/:id', component: UserLayout, // 父组件 children: [ { path: 'profile', component: UserProfile, // 子组件渲染在 UserLayout 的 <router-view> 中 }, { path: 'settings', component: UserSettings } ] } ];
- 2、父组件模板
html<!-- UserLayout.vue --> <template> <div> <h2>用户中心</h2> <router-view></router-view> <!-- 子路由组件在此渲染 --> </div> </template>
路由插槽:暴露一个插槽,用来渲染路由组件。当想要获得其他功能时,插槽提供了额外的扩展性。
html<router-view v-slot="{ Component }"> <component :is="Component" /> </router-view> <!-- 等价于 <router-view /> -->
过渡动画:用 <transition> 包裹 router-view 实现路由切换动画。
html<template> <router-view v-slot="{ Component }"> <transition name="fade" mode="out-in"> <component :is="Component" /> </transition> </router-view> </template> <style> .fade-enter-active, .fade-leave-active { transition: opacity 0.3s; } .fade-enter-from, .fade-leave-to { opacity: 0; } </style>
组件缓存:用 <keep-alive> 包裹 router-view 缓存组件状态。
html<keep-alive> <router-view></router-view> </keep-alive>
传递Props:通过路由配置向组件传递 Props
jsconst routes = [ { path: '/user/:id', component: UserProfile, props: true // 将路由 params 作为 props 传递(如 :id → props.id) }, { path: '/about', component: About, props: { staticData: 'Hello' } // 传递静态对象 }, { path: '/dynamic', component: Dynamic, props: (route) => ({ query: route.query.q }) // 函数模式动态生成 props } ];
路由元信息:
- 1、结合路由元信息 meta 控制视图逻辑。
jsconst routes = [ { path: '/admin', component: AdminDashboard, meta: { requiresAuth: true } } ];
- 2、在组件中访问元信息。
jsexport default { mounted() { if (this.$route.meta.requiresAuth) { // 检查权限逻辑 } } }
注意事项:
- 唯一根元素:每个router-view对应路由配置中的一个组件,确保组件模板有唯一根元素,Vue3支持多根节点。
- 命名视图匹配:若路由配置未提供对应名称的组件,命名视图区域将渲染为空。
- 性能优化:
- 使用 keep-alive 缓存高频访问的页面。
- 按需加载路由组件/异步组件提升首屏速度。
Router
创建router
createRouter()@4
createRouter():({history,routes,scrollBehavior?,...})
,是 VueRouter4 中用于 创建路由实例 的核心函数。替代了 VueRouter3 的 new VueRouter()。
history:
RouterHistory
,指定路由的历史模式。有以下三种内置模式:- createWebHistory():
(base?)
,HTML5模式,无哈希。 - createWebHashHistory():
(base?)
,哈希模式,兼容旧浏览器。 - createMemoryHistory():
(base?)
,内存模式,SSR或测试环境使用。
- createWebHistory():
routes:
RouteRecordRaw[]
,定义路由配置的数组。路由对象 RouteRecordRaw 包含以下常见属性:- path:
string
,路由路径,支持动态参数,如/user/:id
。 - name:
string
,路由唯一名称,用于编程式导航。- component:
Component|()=>import()
,对应组件或异步组件函数。
- component:
- components:
object
,命名视图配置,用于多视图场景。 - redirect:
string|object
,重定向目标。 - children:
RouteRecordRaw[]
,嵌套路由配置。 - meta:
any
,路由元信息,用于权限控制等。 - props:
boolean|object|function
,向组件传递 Props。
- path:
scrollBehavior?:
(to,from,savedPosition)=>PositionResult|Promise
,控制页面滚动行为。to:
string|object
,目标路由地址。from:
string|object
,来源路由地址。savedPosition:
Position|null
,浏览器前进/后退时记录的滚动位置。返回:
position:
PositionResult|Promise
,可指定滚动位置({ top: number, left: number }
)、滚动到指定选择器({ selector: string }
)或保持原位(false
)。
linkActiveClass?:
string
,默认:router-link-active
,当目标路由是当前路由的子路径时激活 CSS 类名。linkExactActiveClass?:
string
,默认:router-link-exact-active
,仅当目标路由与当前路由完全匹配时激活 CSS 类名。parseQuery:
(search)=>Record<string,any>
,自定义查询参数 query 的解析函数。stringifyQuery:
(query)=>string
,自定义查询参数 query 的序列化函数。fallback:
boolean
,默认:true
,在不支持 history.pushState 的浏览器中,是否回退到哈希模式返回:
router:
Router
,返回一个路由实例,包含以下核心方法/属性:- addRoute():
()
,动态添加路由。 - removeRoute():
()
,移除路由。 - hasRoute():
()
,检查路由是否存在。 - getRoutes():
()
,获取当前路由配置。 - beforeEach():
()
,全局导航守卫-前置。 - afterEach():
()
,全局导航守卫-后置。 - push():
()
,编程式导航-前进。 - replace():
()
,编程式导航-替换。
- addRoute():
语法:
控制页面滚动行为:
jsscrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition; // 恢复历史滚动位置 } else if (to.hash) { return { selector: to.hash }; // 滚动到锚点 } else { return { top: 0 }; // 滚动到顶部 } }
使用qs库处理嵌套对象:
jsimport qs from 'qs'; parseQuery: (search) => qs.parse(search, { ignoreQueryPrefix: true }), stringifyQuery: (query) => qs.stringify(query),
注意事项:
- 路由懒加载:使用
() => import()
语法实现组件按需加载。 - TS支持:确保定义路由时使用
RouteRecordRaw
类型,以获得类型检查和自动补全。 - 动态路由:通过
router.addRoute()
可在运行时动态添加路由。
- 路由懒加载:使用
示例:完整配置
jsimport { createRouter, createWebHistory } from 'vue-router'; import Home from '../views/Home.vue'; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), // 基路径 routes: [ { path: '/', name: 'Home', component: Home, meta: { title: '首页' } }, { path: '/about', name: 'About', component: () => import('../views/About.vue'), meta: { requiresAuth: true } } ], scrollBehavior(to, from, savedPosition) { return savedPosition || { top: 0 }; }, linkActiveClass: 'active-link', linkExactActiveClass: 'exact-active-link' }); export default router;
createWebHashHistory()
createWebHashHistory():(base?)
,用于创建基于 哈希模式(Hash Mode) 的路由历史记录。
- base?:
string
,默认:''
,表示应用的基础路径,所有路由将相对于该路径解析。 - 返回:
- history:
RouterHistory
,返回一个RouterHistory对象,用于 Vue Router 的配置。 - 语法:
- base规范化:
- 自动添加前导斜杠,如
my-app
→/my-app
。 - 尾部斜杠会被保留,如传入
/my-app/
则保持为/my-app/
。
- 自动添加前导斜杠,如
- base设置路由前缀:部署时可以通过base设置路由前缀,如
/my-app/
。
- base规范化:
- 特性:
- 哈希模式特点:
- URL 结构: 路由路径位于
#
之后,如https://example.com/#/about
。 - 无服务器配置要求: 哈希变化不会触发页面请求,服务器只需返回单个 HTML 文件。
- 监听机制: 通过
hashchange
事件响应路由变化,兼容性良好。
- URL 结构: 路由路径位于
- 哈希模式特点:
- 示例:设置路由前缀js
import { createRouter, createWebHashHistory } from 'vue-router' const router = createRouter({ history: createWebHashHistory('/my-app/'), // 路由前缀为 /my-app/ routes: [ // 定义路由... ] }) // 部署后路径URL为:https://example.com/my-app/#/home
createWebHistory()
createWebHistory():(base?)
,用于创建基于 HTML5 History API 的路由历史记录,也称为“历史模式”。
base?:
string
,默认:''
,表示应用的基础路径,所有路由将相对于该路径解析。返回:
history:
RouterHistory
,返回一个RouterHistory对象,用于 Vue Router 的配置。语法:
base规范化:
- 自动添加前导斜杠,如
my-app
→/my-app
。 - 尾部斜杠会被保留,如传入
/my-app/
则保持为/my-app/
。
- 自动添加前导斜杠,如
base设置路由前缀:部署时可以通过base设置路由前缀,如
/my-app/
。服务器配置:
- Nginx:
shlocation / { try_files $uri $uri/ /index.html; }
- Apache:
shRewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L]
特性:
- 历史模式特点:
- URL结构:URL 路径无
#
,如https://example.com/about
,更符合标准 URL 规范。 - 依赖HTML5 History API:使用 pushState() 和 replaceState() 操作浏览历史记录,兼容现代浏览器。
- 服务器配置要求:直接访问子路径如
https://example.com/about
时,需确保服务器返回应用入口文件如index.html
,否则会触发 404 错误。 - SPA友好:适合SPA,但需配合服务器配置。
- URL结构:URL 路径无
- 历史模式特点:
注意事项:
- 部署路径匹配:若应用部署在子目录,如
/my-app/
,需同时配置 base 参数和服务器路径规则。 - 兼容性:不支持 IE9 及以下浏览器,需 Polyfill 或降级为哈希模式。
- 开发环境:Vue CLI 或 Vite 的开发服务器已默认支持 History 模式,无需额外配置。
- 部署路径匹配:若应用部署在子目录,如
示例:
jsimport { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory('/my-app/'), // 基础路径为 /my-app/ routes: [ { path: '/', component: Home }, { path: '/about', component: About } ] }) // 部署后路径URL为:https://example.com/my-app/home
useRouter()
useRouter():()
,用于在组件中访问全局的 路由器实例(Router Instance),从而实现编程式导航和路由管理。
返回:
router:
Router
,返回路由器实例,包含 Vue Router 的所有导航方法和属性。语法:
tsimport { useRouter } from 'vue-router'; // 在 setup() 或 <script setup> 中调用 const router = useRouter();
特性:
TS类型支持:
对比useRoute():
函数 返回值 用途 useRouter()
Router
实例编程式导航、动态路由管理、访问全局路由配置。 useRoute()
Route
对象(当前路由)获取当前路由的路径、参数、查询参数等信息。
常见用途:
编程式导航:
ts// 导航到路径 router.push('/home'); // 导航到命名路由并传递参数 router.push({ name: 'user', params: { id: '123' } }); // 替换当前路由 router.replace('/login'); // 后退一步 router.back();
动态路由管理:
js// 添加动态路由 router.addRoute({ path: '/admin', name: 'admin', component: AdminPanel, }); // 检查路由是否存在 const exists = router.hasRoute('admin'); // 移除路由 router.removeRoute('admin');
获取当前路由信息:
js// 访问响应式当前路由对象 const currentPath = router.currentRoute.value.path; const queryParams = router.currentRoute.value.query;
注意事项:
- 仅限组合式API:useRouter() 必须在 setup() 函数或 script setup 中使用。
动态路由
addRoute()
router.addRoute():(parentName?,route)
,是 Vue Router 提供的动态路由管理方法,允许在运行时向路由器实例添加新的路由规则。适用于需要根据用户权限、功能模块懒加载等场景动态扩展路由表的情况。
parentName?:
string | symbol
,父路由的 name,用于将新路由添加为指定父路由的子路由。route:
RouteRecordRaw
,要添加的路由配置对象,结构与静态路由配置一致。返回:
removeRoute:
()=>void
,返回一个无参函数,调用该函数可 移除 刚添加的路由。语法:
- 添加顶层路由:
tsrouter.addRoute(route: RouteRecordRaw): () => void
- 添加嵌套路由:要求父路由有 name 属性。
tsrouter.addRoute(parentName: string | symbol, route: RouteRecordRaw): () => void
特性:
- 立即生效:新路由添加后,导航至该路由 无需刷新页面。
- 覆盖检查:若添加的路与现有路由 name 或 path 重复,后者将覆盖前者。
- 嵌套路由:通过指定 parentName,可将路由添加为子路由,父路由需已存在。
- 导航守卫:可在导航守卫中动态添加路由,实现按需加载。
常见用途:
添加顶层路由:
jsconst newRoute = { path: '/dashboard', name: 'dashboard', component: () => import('./views/Dashboard.vue'), meta: { requiresAuth: true } }; // 添加路由 const removeRoute = router.addRoute(newRoute); // 导航到新路由 router.push('/dashboard'); // 移除路由(可选) // removeRoute();
添加嵌套路由:
js// 父路由需已存在且具有 name 属性 const parentRoute = { path: '/admin', name: 'admin', component: AdminLayout }; // 先添加父路由 router.addRoute(parentRoute); // 添加子路由 router.addRoute('admin', { path: 'users', component: AdminUsers, meta: { role: 'admin' } });
动态模块加载:
js// 在导航守卫中按需添加路由 router.beforeEach(async (to) => { if (to.meta.requiresPro && !isProUser()) { // 动态加载 Pro 模块路由 const proRoutes = await loadProRoutes(); proRoutes.forEach(route => router.addRoute(route)); return to.fullPath; // 重试导航 } });
注意事项:
组件懒加载:动态导入组件
() => import(...)
可优化性能。内存管理:及时移除不再需要的路由,如用户退出时,防止内存泄漏。
父路由不存在:若指定的 parentName 无效,控制台会抛出警告,但不会中断程序。
ts// 错误示例:父路由名称不存在 router.addRoute('invalidParent', { path: 'child', component: Child }); // 控制台警告:父路由未找到,路由未被添加
removeRoute()
router.removeRoute():(name)
,是 Vue Router 提供的动态路由管理方法,用于在运行时通过路由名称或addRoute()返回的移除函数来删除路由。已注册的路由规则。适用于需要根据用户权限、模块卸载等场景动态调整路由表的场景。
name:
string | symbol
,要删除的路由的名称,需在添加路由时显式定义 name 字段。语法:
- 通过路由名称移除:
tsrouter.removeRoute(name: string | symbol): void
- 通过 addRoute() 返回的函数移除:
tsconst removeRoute = router.addRoute(newRoute); removeRoute(); // 直接调用函数,无需参数
特性:
- 删除路由规则:移除指定名称的路由及其所有子路由。
- 立即生效:路由删除后,导航至该路径将触发 404 错误,除非其他路由匹配。
- 依赖清理:若父路由被删除,其所有子路由也会被自动移除。
- 静默处理:尝试删除不存在的路由不会报错,但控制台会输出警告。
常见用途:
通过名称删除路由:
js// 添加路由时定义 name router.addRoute({ path: '/admin', name: 'admin', // 必须定义 name component: AdminPage }); // 通过名称删除 router.removeRoute('admin');
通过返回的函数删除路由:
js// 添加路由并获取移除函数 const removeAdminRoute = router.addRoute({ path: '/admin', component: AdminPage }); // 调用函数移除路由 removeAdminRoute();
删除嵌套路由:
js// 添加父路由和子路由 router.addRoute({ path: '/dashboard', name: 'dashboard', component: Dashboard, children: [ { path: 'stats', name: 'stats', component: Stats } ] }); // 删除父路由(同时删除子路由 'stats') router.removeRoute('dashboard');
注意事项:
- 必须定义name:若要通过 removeRoute(name) 删除,路由需在配置中显式定义 name。
- 避免重复删除:多次删除同一路由不会报错,但会触发控制台警告。
- 导航处理:删除当前激活的路由可能导致页面无响应,建议先跳转到其他路径。
- 性能影响:频繁添加/删除路由可能影响性能,建议批量操作。
- 删除不存在的路由:静默忽略,控制台警告:
[Vue Router] Route with name 'xxx' does not exist
。 - 未定义name的路由:无法通过 removeRoute(name) 删除,需使用 addRoute() 返回的函数。
hasRoute()
router.hasRoute():(name)
,用于检查指定名称的路由是否已注册到路由器实例中。
name:
string | symbol
,要检查的路由名称,需在路由配置中显式定义 name 字段。返回:
exists:
boolean
,指定名称的路由是否存在。特性:
- 基于名称检查:仅通过路由的 name 字段判断是否存在,不支持路径或动态参数匹配。
- 动态路由支持:可检测通过 addRoute() 动态添加的路由。
- 嵌套路由处理:无论路由是顶层还是嵌套子路由,只要名称匹配即返回 true。
- 静默验证:无效参数,如未定义名称或类型错误,直接返回 false,不抛出错误。
常见用途:
检查静态路由是否存在:
js// 路由配置中定义名称 const routes = [ { path: '/admin', name: 'admin', component: AdminPage } ]; // 检查路由是否存在 const exists = router.hasRoute('admin'); console.log(exists); // 输出:true
验证动态添加的路由:
js// 动态添加路由 router.addRoute({ path: '/dashboard', name: 'dashboard', component: Dashboard }); // 检查动态路由 console.log(router.hasRoute('dashboard')); // 输出:true
处理不存在的路由:
js// 检查未定义的路由 console.log(router.hasRoute('unknown')); // 输出:false // 检查无效参数类型 console.log(router.hasRoute(123)); // TypeScript 报错,运行时返回 false
getRoutes()@4
router.getRoutes():()
,是 Vue Router 4 提供的方法,用于获取当前路由器实例中所有已注册的路由记录的完整列表。
返回:
routes:
RouteRecordNormalized[]
,标准化后的路由记录数组。特性:
标准化路由记录:返回的路由记录是 Vue Router 内部处理后的标准化格式,可能与初始配置不同,如多视图组件会映射到 components 对象。
包含动态路由:通过 router.addRoute() 动态添加的路由也会被包含在内。
嵌套路由展开:子路由会以扁平化结构存在于数组中,但通过 children 属性可访问层级关系。
响应式数据:返回的数组是静态快照,路由变化后需重新调用 getRoutes() 获取最新状态。
TS类型支持:通过 RouteRecordNormalized 类型可获取完整类型提示。
tsimport type { RouteRecordNormalized } from 'vue-router'; const routes: RouteRecordNormalized[] = router.getRoutes();
常见用途:
获取所有路由记录:
js// 获取路由列表 const routes = router.getRoutes(); // 打印路由路径和名称 routes.forEach(route => { console.log(`路径: ${route.path}, 名称: ${route.name || '未命名'}`); });
动态生成导航菜单:
html<template> <ul> <li v-for="route in visibleRoutes" :key="route.path"> <router-link :to="route.path">{{ route.meta?.title }}</router-link> </li> </ul> </template> <script setup> import { useRouter } from 'vue-router'; const router = useRouter(); const visibleRoutes = router.getRoutes().filter(route => !route.meta?.hidden); </script>
注意事项:
- 不修改原始配置:返回的路由记录是只读的,直接修改不会影响实际路由表。
- 命名视图处理:若路由配置中使用了命名视图,如
<router-view name="sidebar">
,components 属性会包含所有命名组件。
导航守卫
beforeEach()
router.beforeEach():(guard)
,全局前置导航守卫,用于在每次路由跳转前执行自定义逻辑,如权限校验、数据预加载等。
guard:
(to, from, next?)=>NavigationGuardReturn | Promise<NavigationGuardReturn>
,回调函数。to:
RouteLocationNormalized
,目标路由对象,包含路径、参数、查询参数、哈希等完整信息。from:
RouteLocationNormalized
,来源路由对象,当前正要离开的路由。next?:
NavigationGuardNext:(value)=>void
,控制导航行为的函数,推荐用返回值替代。返回:
navigationGuard:
NavigationGuardReturn | Promise<NavigationGuardReturn>
,返回值类型:void
:无返回值,需显式调用 next()。boolean
:true 继续导航,false 中断导航。string
:重定向到新路径,如/login
。RouteLocationRaw
:重定向到路由对象,如{ name: 'home' }
。Promise
:异步操作完成后解析为上述类型之一。Error
:抛出错误,中断导航并触发全局错误处理router.onError()
。
返回:
removeGuard:
() => void
,一个移除该守卫的函数,调用后取消监听。特性:
执行顺序:
- 全局前置守卫按注册顺序依次执行。
- 若某个守卫返回 false 或未调用 next(),后续守卫将不再执行,导航被中断。
异步支持:守卫函数可以返回 Promise,Vue Router 会等待其解析后再继续导航流程。
next()函数控制方式:
next()
:继续导航至目标路由。next(false)
:中断当前导航,停留在当前页面。next('/path')
:重定向到指定路径。next({name: 'route'})
:重定向到指定路由配置对象。next(error)
:抛出错误,中断导航并触发 router.onError()。
移除守卫:通过
const removeGuard = router.beforeEach(...)
返回的函数可手动移除守卫。对比其他守卫:
守卫类型 作用域 触发时机 典型用途 beforeEach
全局 导航开始前 权限校验、日志记录 beforeResolve
全局 导航确认前(异步组件解析后) 最终数据校验 afterEach
全局 导航完成后 埋点统计、页面标题更新 beforeRouteEnter
组件内 组件渲染前 组件初始化前的数据加载
常见用途:
权限校验:用户登录检查。
jsrouter.beforeEach((to, from) => { if (to.meta.requiresAuth && !isUserLoggedIn()) { // 重定向到登录页 return { path: '/login', query: { redirect: to.fullPath } }; } // 允许导航 return true; });
异步数据预加载:
jsrouter.beforeEach(async (to) => { if (to.meta.requiresData) { await loadInitialData(); } return true; // 继续导航 });
兼容 Vue Router3 的 next 用法:
jsrouter.beforeEach((to, from, next) => { if (to.name === 'admin' && !isAdmin()) { next('/403'); // 重定向到无权限页 } else { next(); // 继续导航 } });
注意事项:
- 避免无限循环:确保重定向逻辑不会导致循环,如未登录时重定向到登录页,但登录页又触发重定向。
- next()与返回值的冲突:若同时使用 next() 和返回值,以 next() 的调用为准。推荐优先使用返回值,有更清晰的异步控制。
afterEach()
router.afterEach():(guard)
,全局后置守卫,用于注册一个在 导航完成之后 执行的钩子函数。它不会改变导航结果,常用于执行与导航结果无关的后续处理操作,如埋点统计、页面标题更新等。
guard:
(to,from,failure)
,to:
RouteLocationNormalized
,目标路由对象,包含路径、参数、查询参数、哈希等完整信息。from:
RouteLocationNormalized
,来源路由对象,当前正要离开的路由。failure:
Error|NavigationFailure|undefined
,导航失败的错误对象,成功时为 undefined。
特性:
导航完成后触发:无论导航成功或失败,afterEach 都会在 导航流程完全结束后 触发:
- 成功:所有组件已渲染,路由切换完成。
- 失败:导航被中断,如权限校验未通过。
不控制导航:与 beforeEach 不同,afterEach 无法取消或重定向导航,仅用于后处理操作。
访问导航失败信息:通过 failure 参数可判断导航是否成功。
tsrouter.afterEach((to, from, failure) => { if (failure) { console.error('导航失败:', failure); } else { console.log('导航成功:', to.fullPath); } });
异步操作处理:若需执行异步任务如发送请求,需确保其不影响应用性能。
tsrouter.afterEach(async (to) => { await logNavigation(to.fullPath); // 异步操作 });
避免阻塞主线程:长时间同步操作可能导致页面卡顿,建议使用 setTimeout 或 requestIdleCallback。
常见用途:
页面访问统计:
jsrouter.afterEach((to) => { // 发送埋点数据 trackPageView(to.fullPath); });
动态更新页面标题:
jsrouter.afterEach((to) => { const title = to.meta.title || '默认标题'; document.title = title; });
错误日志记录:
jsrouter.afterEach((to, from, failure) => { if (failure && isNavigationFailure(failure, NavigationFailureType.canceled)) { console.warn('导航被取消:', failure); } });
示例:注册全局后置守卫
jsimport { createRouter, NavigationFailureType, isNavigationFailure } from 'vue-router'; const router = createRouter({ /* 路由配置 */ }); // 注册全局后置守卫 router.afterEach((to, from, failure) => { // 1. 更新页面标题 document.title = to.meta.title || 'My App'; // 2. 记录导航结果 if (failure) { if (isNavigationFailure(failure, NavigationFailureType.aborted)) { console.error('导航被中止:', failure.to.path); } else if (isNavigationFailure(failure, NavigationFailureType.canceled)) { console.warn('用户取消了导航'); } } else { console.log(`从 ${from.path} 跳转到 ${to.path}`); } });
beforeResolve()
router.beforeResolve():()
,全局解析守卫,用于注册一个在 导航被确认之前 执行的钩子函数。
guard:
(to, from, next?)=>NavigationGuardReturn | Promise<NavigationGuardReturn>
,回调函数。to:
RouteLocationNormalized
,目标路由对象,包含路径、参数、查询参数、哈希等完整信息。from:
RouteLocationNormalized
,来源路由对象,当前正要离开的路由。next?:
NavigationGuardNext:(value)=>void
,控制导航行为的函数,推荐用返回值替代。返回:
navigationGuard:
NavigationGuardReturn | Promise<NavigationGuardReturn>
,返回值类型:void
:无返回值,需显式调用 next()。boolean
:true 继续导航,false 中断导航。string
:重定向到新路径,如/login
。RouteLocationRaw
:重定向到路由对象,如{ name: 'home' }
。Promise
:异步操作完成后解析为上述类型之一。Error
:抛出错误,中断导航并触发全局错误处理router.onError()
。
返回:
removeGuard:
() => void
,一个移除该守卫的函数,调用后取消监听。语法:
- 基本使用:
tsrouter.beforeResolve((to, from, next) => { // 逻辑处理 next(); // 必须调用 next() 继续导航 });
- 使用异步函数(推荐):
ts// 或使用异步函数(推荐): router.beforeResolve(async (to, from) => { // 异步逻辑(如数据预加载) return true; // 继续导航 });
特性:
异步处理:通过返回 Promise 或使用 async/await,可优雅处理异步操作。
tsrouter.beforeResolve(async (to, from) => { // 等待异步操作完成 await fetchUserPermissions(); if (!hasAccess(to)) { return '/login'; // 重定向到登录页 } return true; // 继续导航 });
执行时机:beforeResolve 的执行顺序如下:
- 组件内守卫:
beforeRouteLeave
、beforeRouteUpdate
。 - 全局守卫:
beforeEach
。 - 路由独享守卫:
beforeEnter
。 - 解析异步路由组件(懒加载的组件)。
- 组件内守卫:
beforeRouteEnter
。 - 全局解析守卫:
beforeResolve
(最终确认前的最后一步)。
- 组件内守卫:
对比beforeEach:
- beforeEach: 在导航触发时立即执行,不等待异步组件解析。
- beforeResolve: 在所有异步操作完成后执行,适合依赖完整数据的逻辑。
常见用途:
- 数据预加载:确保所有组件和异步数据加载完成后,再进入目标页面。
- 动态路由配置:根据条件动态修改路由元数据或路径。
示例:
jsimport { createRouter } from 'vue-router'; const router = createRouter({ /* 路由配置 */ }); // 注册全局解析守卫 router.beforeResolve(async (to, from) => { try { // 获取必要数据 const data = await loadRequiredData(to.params.id); // 检查权限 if (!data.isAccessible) { return { path: '/403' }; // 无权限时跳转 } return true; } catch (error) { console.error('导航失败:', error); return false; // 中断导航 } });
路由导航
push()
router.push():(to)
,核心导航方法,用于 编程式导航到新路由,支持多种参数形式。
to:
RouteLocationRaw
,指定目标路径,有字符串和对象两种写法。返回:
result:
Promise<NavigationFailure | void>
,导航成功时解析为void
,失败时解析为NavigationFailure
错误对象。语法:
RouteLocationRaw
可以是以下类型之一:- 路径字符串:直接传递目标路径,不支持动态参数和查询参数外的复杂逻辑。
ts// 导航到 /about router.push('/about'); // 导航到带查询参数的路径 router.push('/search?q=vue');
- 路由配置对象:通过对象形式指定路由细节,支持动态参数、查询参数和哈希。
tsinterface RouteLocation { path?: string; // 路径(与 name 二选一) name?: string; // 路由名称(需在路由配置中定义) params?: RouteParams; // 动态路由参数(需与路由定义匹配) query?: LocationQuery; // URL 查询参数(?后的键值对) hash?: string; // 哈希值(#后的内容) replace?: boolean; // 是否替换当前历史记录(默认 false) force?: boolean; // 是否强制跳转(即使路径相同) } router.push({ path: '/login', replace: true // 等同于 router.replace() });
特性:
使用 path + query:
tsrouter.push({ path: '/search', query: { q: 'vue', page: 1 } // URL 变为 /search?q=vue&page=1 });
使用 name + params:动态路由
ts// 路由配置:{ path: '/user/:id', name: 'user' } router.push({ name: 'user', params: { id: 123 } // URL 变为 /user/123 });
混合使用 query 和 hash:
tsrouter.push({ path: '/profile', query: { tab: 'settings' }, hash: '#notifications' // URL 变为 /profile?tab=settings#notifications });
替换当前历史记录:
tsrouter.push({ path: '/login', replace: true // 等同于 router.replace() });
TS类型支持:在 TS 中,通过泛型定义动态参数类型。
ts// 定义路由参数类型 declare module 'vue-router' { interface RouteMeta { requiresAuth?: boolean; } } // 使用类型约束的 params router.push<{ id: string }>({ name: 'user', params: { id: '123' } // ✅ 类型检查通过 });
常见用途:
用户登录后跳转回原页面:
jsrouter.push({ path: '/login', query: { redirect: router.currentRoute.value.fullPath } }); // 登录成功后跳转回原页面 const redirect = router.currentRoute.value.query.redirect; if (typeof redirect === 'string') { router.push(redirect); }
动态表单提交后导航:
jsasync function submitForm() { try { await api.submitForm(data); router.push({ name: 'success' }); // 提交成功跳转 } catch (error) { router.push({ name: 'error', query: { code: error.code } }); // 错误处理 } }
带复杂参数的列表过滤:
jsrouter.push({ name: 'product-list', query: { category: 'electronics', priceMin: 100, priceMax: 500 } });
注意事项:
动态参数类型匹配:若路由定义为
/user/:id
,params 必须包含 id 字段。ts// 正确 ✅ router.push({ name: 'user', params: { id: '123' } }); // 错误 ❌(缺少 id) router.push({ name: 'user' }); // 抛出错误
path 与 params 的冲突:当使用 path 时,params 会被忽略,参数需通过路径占位符传递。
ts// 路由配置:{ path: '/user/:id' } // ✅ 正确(通过路径传递) router.push({ path: '/user/123' }); // ❌ 错误(params 被忽略) router.push({ path: '/user', params: { id: 123 } }); // 导航到 /user
replace()
router.replace():(to)
,编程式导航方法,用于 替换当前浏览器历史记录中的路由,不会新增历史条目。适用于需要隐藏当前导航记录的场景,如登录后跳转,不希望用户通过返回按钮回到登录页。
to:
RouteLocationRaw
,指定目标路径,有字符串和对象两种写法。返回:
result:
Promise<NavigationFailure | void>
,导航成功时解析为void
,失败时解析为NavigationFailure
错误对象。语法:类似push():
路径字符串:直接传递目标路径,不支持动态参数和查询参数外的复杂逻辑。
路由配置对象:通过对象形式指定路由细节,支持动态参数、查询参数和哈希。
特性:
替换历史记录:浏览器历史栈的当前条目被新路由替换,用户点击返回按钮会跳过当前页。
强制导航:通过
force: true
强制跳转,即使目标路径与当前路径相同。tsrouter.replace({ path: '/same-page', force: true });
TS类型支持:
ts// 声明动态参数类型 declare module 'vue-router' { interface RouteParams { id?: string; } } // 使用类型安全的 params router.replace({ name: 'user', params: { id: '123' } }); // ✅ 类型检查通过 router.replace({ name: 'user', params: { role: 'admin' } }); // ❌ 类型错误
对比push():
方法 历史记录行为 典型场景 push()
新增历史条目 常规导航(允许用户返回) replace()
替换当前历史条目 登录后跳转、错误页替换
常见用途:
登录后跳转到首页,禁止返回登录页:
js// 登录成功后替换当前历史记录 router.replace('/home'); // 或使用路由名称 router.replace({ name: 'home' });
back()
router.back():()
,导航方法,用于 返回浏览器历史记录中的上一页,相当于用户点击浏览器的后退按钮。简化了编程式导航中的后退操作。
go()
router.go():(n)
,全局导航方法,用于在 浏览器历史记录栈 中前进或后退指定的步数。行为类似于浏览器的前进/后退按钮。
n:
number
,表示历史记录跳转的步数。n > 0
:向前进 n 步。n < 0
:向后退 n 步。n = 0
:刷新当前页面。n = 1
:等价于router.forward()
(未实现该方法)。n = -1
:等价于router.back()
。超出范围
:静默失败。
特性:
对比其他导航方法:
方法 参数 行为 典型场景 router.go(n)
整数 n
前进/后退 n
步动态控制历史记录跳转 router.back()
无 后退 1 步(简化版) 用户手动触发返回 router.push()
路由对象 新增历史记录并跳转 常规导航 router.replace()
路由对象 替换当前历史记录并跳转 登录后无痕跳转
路由属性
currentRoute
router.currentRoute:RouteLocationNormalized
,只读
,响应式
,用于获取当前激活路由的详细信息。
语法:
- 组合式API:
tsimport { useRouter } from 'vue-router'; const router = useRouter(); console.log(router.currentRoute.value); // 需要 .value 访问(因为是 ref) console.log(router.currentRoute.value.path);
- 选项式API:
tsexport default { mounted() { console.log(this.$router.currentRoute); // 直接访问当前路由对象 console.log(this.$router.currentRoute.path); // 当前路径 } }
特性:
TS类型定义:
tsimport { RouteLocationNormalized } from 'vue-router'; // 显式类型声明 const currentRoute: RouteLocationNormalized = router.currentRoute.value;
RouteLocationNormalized类型:获取方式:
- this.$route
- useRoute()
- this.$router.currentRoute.value
- useRouter().currentRoute.value
常见用途:
在组件外部访问路由:
js// 在非组件文件中(如工具函数) import router from '@/router'; function logCurrentRoute() { console.log(router.currentRoute.value.fullPath); }
获取当前路由信息
导航守卫中对比路由
resolve()
router.resolve():(location)
,用于手动解析路由配置,返回目标路由的标准化信息。适用于需要获取路由路径或匹配的组件等场景。
location:
RouteLocationRaw
,表示要解析的路由位置,支持以下形式:路径字符串:如
/user/123
。路由配置对象:
ts{ name: 'user', // 路由名称(需在配置中定义) params: { id: 123 },// 动态参数 query: { tab: 'info' }, // 查询参数 hash: '#section' // 哈希值 }
返回:
resolved:
RouteLocation & { href: string }
,返回一个包含以下属性的对象:- href:
string
,完整 URL,包含路径、查询参数和哈希。 - route:
Route
,标准化后的路由对象。 - location:
RouteLocation
,路由的标准化位置信息。 - redirectedFrom:
Route|undefined
,若存在重定向,返回原始路由对象。
- href:
特性:
对比currentRoute:
特性 router.currentRoute
router.resolve()
用途 获取当前路由状态 解析目标路由信息 响应式 ✅ 是(返回 Ref<RouteLocation>
)❌ 否(返回普通对象) 触发导航 ❌ 否 ❌ 否 参数要求 ❌ 无需参数 ✅ 必须传入目标位置(路径或对象) 动态性 实时反映当前路由变化 静态解析,结果固定 典型使用场景 获取当前路径、参数、查询等 生成链接、检查路由是否存在
常见用途:
手动生成完整URL:
jsconst resolved = router.resolve({ name: 'product', params: { id: 456 }, query: { ref: 'home' } }); console.log(resolved.href); // 输出:'/product/456?ref=home'
获取匹配的路由记录:
jsconst resolved = router.resolve('/admin/dashboard'); console.log(resolved.route.matched); // 输出匹配的路由数组
SSR中生成链接:
js// 在服务端生成静态链接 const href = router.resolve('/user/123').href; res.send(`<a href="${href}">用户详情</a>`);
options
router.options:RouterOptions
,只读
,用于访问创建路由实例时传入的 全局配置对象。它包含路由初始化时的所有原始配置参数,适用于调试或动态读取全局路由配置的场景。
语法:
- 组合式API:
ts// 组合式 API 中访问 import { useRouter } from 'vue-router'; const router = useRouter(); console.log(router.options); // 输出路由配置对象
- 选项式API:
ts// 选项式 API 中访问 export default { mounted() { console.log(this.$router.options); // 通过组件实例访问 } }
特性:
TS类型定义:RouterOptions
tsinterface RouterOptions { routes: RouteRecordRaw[]; // 路由配置数组 history: RouterHistory; // 路由模式(history/hash) linkActiveClass?: string; // 激活链接的 CSS 类名 linkExactActiveClass?: string; // 精确激活链接的 CSS 类名 scrollBehavior?: ScrollBehavior; // 滚动行为控制函数 parseQuery?: (query: string) => any; // 自定义查询参数解析逻辑 stringifyQuery?: (query: any) => string; // 自定义查询参数序列化逻辑 strict?: boolean; // 是否严格匹配路径末尾斜杠 sensitive?: boolean; // 是否区分路径大小写 end?: boolean; // 路径匹配是否允许子路径 // ...其他高级配置(如路由守卫等) }
常见用途:
访问全局路由表:
js// 获取所有路由配置 const allRoutes = router.options.routes; console.log('应用总路由数:', allRoutes.length);
检查路由模式:
js// 判断当前是否使用哈希模式 const isHashMode = router.options.history instanceof createWebHashHistory; console.log('是否哈希模式:', isHashMode);
动态读取链接类名配置:
js// 获取全局激活链接类名 const activeClass = router.options.linkActiveClass || 'active-link'; console.log('激活类名:', activeClass);
注意事项:
- 动态路由限制:通过 router.addRoute() 动态添加的路由不会更新 options.routes。
SSR
isReady()
router.isReady():()
,是 Vue Router4 引入的 异步方法,用于检查路由是否已完成初始导航,即首次路由解析。可确保在路由完全准备就绪后再执行客户端激活或异步数据加载操作。
返回:
result:
Promise<void>
,当路由完成初始导航时解析。特性:
初始导航完成:
若路由已解析,如当前 URL 对应的路由匹配完成且组件加载完毕,Promise 立即解析。
若路由尚未解析,如存在异步组件或懒加载路由,则等待初始导航完成后解析。
SSR支持:在 SSR 中,客户端激活(hydration)前调用 router.isReady(),可避免因路由未就绪导致的客户端与服务端内容不匹配问题。
常见用途:
客户端入口文件等待路由就绪:
js// 创建 Vue 应用实例 const app = createApp(App); app.use(router); // 等待路由准备就绪后挂载应用 router.isReady().then(() => { app.mount('#app'); });
服务端渲染激活过程:
js// 服务端返回的 HTML 包含初始化数据 // 客户端激活前确保路由已解析 router.isReady().then(() => { // 执行客户端激活 hydrateApp(); });
异步路由加载完成后操作:
js// 动态添加路由后等待初始化完成 router.addRoute({ path: '/admin', component: Admin }); router.isReady().then(() => { console.log('路由已更新,可安全跳转'); });
与导航守卫配合:在 beforeEach 或 beforeResolve 中处理异步逻辑时,isReady() 确保所有守卫执行完毕。
错误处理
onError()
router.onError():(handler)
,全局错误处理钩子,用于捕获在 导航过程中发生的异常或失败,如异步组件加载失败、导航被中止等。
handler:
(err)=>void
,回调函数,接收一个错误对象。- err:
Error & {message,type,from,to}
,错误对象为 Error 类型,但可能包含 Vue Router 扩展的额外属性。message:
string
,错误描述信息。type:
{aborted,cancelled,duplicated}
,错误类型。from:
RouteLocationNormalized
,触发错误的来源路由对象,当前正要离开的路由。to:
RouteLocationNormalized
,触发错误的目标路由对象,即将进入的路由。
- err:
返回:
removeErrorHandler:
()=>void
,一个移除该错误监听的函数,调用后取消监听。特性:
- 全局错误监听:捕获所有未处理的导航错误,如组件加载失败、导航守卫中抛出异常等。
- 错误类型判断:使用
isNavigationFailure(error, type)
工具函数精准判断错误类型。 - 异步组件加载失败:当使用懒加载
() => import('./Component.vue')
的组件加载失败时,触发错误。 - 移除监听器:调用返回的函数可移除错误监听,避免内存泄漏。
常见用途:
注册全局错误处理:
jsimport { NavigationFailureType, isNavigationFailure } from 'vue-router'; router.onError((error) => { // 判断是否为导航失败错误 if (isNavigationFailure(error, NavigationFailureType.aborted)) { console.error('导航被中止:', error.message); } else if (isNavigationFailure(error, NavigationFailureType.cancelled)) { console.error('导航被取消:', error.message); } else { // 处理其他错误(如组件加载失败) console.error('未知导航错误:', error); router.push('/error-page'); } });
移除错误监听:
jsconst removeErrorHandler = router.onError(handleError); // 在合适时机移除监听 removeErrorHandler();
处理异步组件加载失败:
jsrouter.onError((error) => { // 检查错误是否为加载组件失败 if (error.message.includes('Failed to fetch dynamically imported module')) { console.error('组件加载失败:', error); router.replace('/load-error'); // 跳转到错误页 } });
注意事项:
- ****:
- ****:
示例:
js
Route
useRoute()
useRoute():()
,用于在组件中访问当前路由的响应式信息。
返回:
route:
RouteLocationNormalized
,响应式
,返回响应式的路由对象,包含以下关键属性:path:
string
,当前路由的路径。始终以/
开头。name:
string| symbol| undefined
,路由配置中定义的名称,未命名路由为 undefined。params:
Record<string, string>
,动态路由参数。query:
Record<string, string| string[]>
,URL 查询参数。hash:
string
, URL 哈希值,始终以#
开头。fullPath:
string
,完整 URL,包含路径、查询参数和哈希。matched:
RouteRecordNormalized[]
,当前路由匹配的所有嵌套路由记录,按父到子顺序排列。meta:
Record<string, unknown>
,路由元数据,自定义字段,如权限标识。redirectedFrom:
RouteLocation| undefined
,若当前路由是重定向而来,指向原始路由对象。
语法:
- 组合式API:setup() 或 script setup
tsimport { useRoute } from 'vue-router'; // 在 setup() 或 <script setup> 中调用 const route = useRoute();
- 选项式API:
jsconst userId = this.$route.params.id const page = this.$route.query.page
特性:
响应式依赖:route 对象是响应式的,但其属性需在响应式上下文中使用,如 computed 或 watch,才能触发更新。
路由匹配失败:若当前路径未匹配任何路由,
route.matched
为空数组,需处理 404 场景。TS类型扩展:可通过扩展 RouteMeta 接口增强 route.meta 的类型安全。
ts// 在全局类型声明文件(如 vue-router.d.ts)中定义: declare module 'vue-router' { interface RouteMeta { requiresAuth?: boolean; title?: string; } }
常见用途:
获取动态路由参数:
js// 路由配置:{ path: '/user/:id', component: User } const route = useRoute(); const userId = route.params.id; // 类型为 string
读取查询参数:
js// 访问 URL:/search?q=vue&page=1 const searchQuery = route.query.q; // 类型为 string | string[] const currentPage = route.query.page; // 类型为 string | string[]
监听路由变化:
jsimport { watch } from 'vue'; watch( () => route.params.id, (newId) => { console.log('用户ID变化:', newId); fetchUserData(newId); } );
根据元数据控制UI:
ts// 路由配置:{ path: '/admin', meta: { requiresAuth: true } } const showAdminPanel = computed(() => route.meta.requiresAuth);
示例:完整示例
html<script setup> import { useRoute } from 'vue-router'; import { computed } from 'vue'; const route = useRoute(); // 动态获取用户ID const userId = computed(() => route.params.id); // 根据查询参数过滤内容 const searchTerm = computed(() => route.query.q || ''); // 检查是否需要登录 const requiresAuth = computed(() => route.meta.requiresAuth || false); </script> <template> <div v-if="requiresAuth"> <h1>用户ID:{{ userId }}</h1> <p>搜索关键词:{{ searchTerm }}</p> </div> </template>
path
route.path:string
,只读
,响应式
,当前路由的路径字符串,用于获取或监听路由的路径部分,不含查询参数和哈希。
语法:
- 组合式API:setup() 或 script setup
ts// 组合式 API 中通过 useRoute() 获取 import { useRoute } from 'vue-router'; const route = useRoute(); const path: string = route.path;
- 选项式API:
ts// 选项式 API 中通过 this.$route 访问 export default { computed: { currentPath() { return this.$route.path; } } }
特性:
动态路由匹配:路径包含动态参数时,route.path 返回解析后的实际路径。
js// 路由配置:{ path: '/user/:id' } // 访问 URL:/user/123 console.log(route.path); // 输出 "/user/123"
嵌套路由:返回完整路径,包含父路由和子路由。
js// 路由配置:{ path: '/parent', children: [{ path: 'child' }] } // 访问 URL:/parent/child console.log(route.path); // 输出 "/parent/child"
别名:显示用户实际访问的路径,而非原始配置路径。
js// 路由配置:{ path: '/home', alias: '/welcome' } // 访问 URL:/welcome console.log(route.path); // 输出 "/welcome"
哈希和查询参数:route.path 仅包含路径部分,不包含
?
后的查询参数和#
后的哈希。js// 访问 URL:/search?q=vue#results console.log(route.path); // 输出 "/search" console.log(route.query); // { q: 'vue' } console.log(route.hash); // "#results"
对比其他路由属性:
属性 作用 示例(URL: /user/123?q=vue#info
)path
路径部分 /user/123
fullPath
完整路径(含查询和哈希) /user/123?q=vue#info
params
动态路由参数 { id: '123' }
query
查询参数 { q: 'vue' }
hash
哈希值 #info
常见用途:
根据路径动态渲染内容:
html<template> <div v-if="route.path === '/dashboard'"> <Dashboard /> </div> <div v-else-if="route.path.startsWith('/user/')"> <UserProfile /> </div> </template> <script setup> import { useRoute } from 'vue-router'; const route = useRoute(); </script>
导航守卫中判断路径:
jsrouter.beforeEach((to, from) => { if (to.path === '/admin' && !isAdmin) { return '/login'; } });
监听路径变化:
jsimport { watch } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); watch( () => route.path, (newPath, oldPath) => { console.log(`路由从 ${oldPath} 切换至 ${newPath}`); } );
注意事项:
只读属性:修改 route.path 无效,需通过 router.push() 或 router-link 变更路由。
js// 正确方式 router.push('/new-path'); // 错误方式(无效) route.path = '/new-path';
性能优化:频繁监听路径变化时,避免在 watch 中执行高开销操作,可结合防抖或节流。
隐藏路径信息:若路径包含敏感数据如用户 ID,避免在客户端直接暴露,需后端校验权限。
fullPath
route.fullPath:string
,只读
,响应式
,用于获取当前路由的 完整路径,包含路径、查询参数和哈希。
语法:
- 组合式API:setup() 或 script setup
ts// 组合式 API 中通过 useRoute() 获取 import { useRoute } from 'vue-router'; const route = useRoute(); const fullPath: string = route.fullPath;
- 选项式API:
ts// 选项式 API 中通过 this.$route 访问 export default { computed: { currentFullPath() { return this.$route.fullPath; } } }
特性:
包含完整路径:包含完整的 URL 信息,包括路径、查询参数和哈希。
ts// 访问 URL: /user/123?role=admin#settings console.log(route.fullPath); // 输出 "/user/123?role=admin#settings"
编码一致性:查询参数和哈希中的特殊字符会被自动编码,确保 URL 规范。
jsrouter.push('/search?q=vue router'); console.log(route.fullPath); // 输出 "/search?q=vue%20router"
SSR:在 SSR 中,fullPath 反映客户端实际访问的 URL,需确保与服务器端路由一致。
注意事项:
- 只读属性:修改 route.fullPath 无效,需通过 router.push() 或 router-link 变更路由。
- 性能优化:频繁监听路径变化时,避免在 watch 中执行高开销操作,可结合防抖或节流。
meta
route.meta:Record<string, unknown>
,响应式
,用于获取当前路由的元数据。
语法:
- 组合式API:setup() 或 script setup
tsimport { useRoute } from 'vue-router'; const route = useRoute(); if (route.meta.title) { document.title = route.meta.title; }
- 选项式API:
tsexport default { mounted() { if (this.$route.meta.requiresAuth) { console.log('此页面需要登录'); } } }
- 在导航守卫中访问meta:在导航守卫中提供
to.meta
或from.meta
访问。
jsrouter.beforeEach((to) => { if (to.meta.requiresAuth && !isLoggedIn()) { return '/login'; } });
特性:
嵌套路由的meta:子路由的 meta 不会自动合并父路由的元数据。需手动处理或遍历 matched 数组获取全部元数据。
tsrouter.afterEach((to) => { const metaList = to.matched.map(record => record.meta); const requiresAuth = metaList.some(meta => meta.requiresAuth); });
TS类型定义:在 TS 中,扩展 RouteMeta 接口以定义具体的元数据字段。
ts// 在项目中的类型声明文件(如:vue-router.d.ts)中添加: import 'vue-router'; declare module 'vue-router' { interface RouteMeta { requiresAuth?: boolean; // 是否需要认证 title?: string; // 页面标题 permissions?: string[]; // 权限列表 // 其他自定义字段... } }
常见用途:
权限控制:标记需要登录或特定权限的路由。
jsmeta: { requiresAuth: true, roles: ['admin', 'editor'] }
jsrouter.beforeEach((to) => { const requiresAuth = to.matched.some(record => record.meta.requiresAuth); if (requiresAuth && !checkAuth()) { return { path: '/login', query: { redirect: to.fullPath } }; } });
SEO优化:设置页面标题和描述。
jsmeta: { title: '产品列表', description: '浏览所有产品' }
布局切换:指定页面使用的布局组件。
jsmeta: { layout: 'dashboard' }
name
route.name:string| symbol| undefined
,只读
,用于获取当前路由的 名称,该名称在路由配置中定义。允许通过名称而非路径进行导航和逻辑处理。
语法:
- 路由配置:
jsconst routes = [ { path: '/user/:id', name: 'user', // 定义路由名称 component: UserComponent } ];
访问路由名称:
- 组合式API:
js// 组合式 API import { useRoute } from 'vue-router'; const route = useRoute(); console.log(route.name); // 输出:'user'
- 选项式API:
js// 选项式 API this.$route.name; // 输出:'user'
特性:
唯一性:每个路由的 name 应唯一,避免冲突,重复名称可能导致不可预测的行为。
静态性:name 在路由配置中定义后不可动态修改,与路径参数无关。
嵌套路由:子路由的 name 独立于父路由,无层级关系。
TS类型约束:在 TS 中,可通过字面量类型约束路由名称,提供更严格的类型检查。
ts// 定义路由配置 const routes = [ { path: '/', name: 'home', component: HomeComponent }, { path: '/about', name: 'about', component: AboutComponent } ] as const; // 使用 as const 固定类型 // 导航时获得自动类型提示 router.push({ name: 'home' }); // ✅ 正确 router.push({ name: 'contact' }); // ❌ 类型错误
常见用途:
编程式导航:通过名称跳转,避免硬编码路径。
js// ✅ 跳转到用户详情页(需提供 params) router.push({ name: 'user', params: { id: 123 } }); // ❌ 错误示例(缺少必要参数) router.push({ name: 'user' }); // 抛出错误:Missing required param "id"
模板中的动态链接:在 router-link 中使用名称生成链接。
html<router-link :to="{ name: 'user', params: { id: 123 }}"> 用户详情 </router-link>
导航守卫中的逻辑判断:根据路由名称控制权限或行为。
jsrouter.beforeEach((to) => { if (to.name === 'admin' && !isAdmin()) { return '/login'; } });
注意事项:
- 未定义名称的路由:未配置 name 的路由无法通过名称访问,route.name 为 undefined。
params
route.params:Record<string, string|string[]>
,只读
,响应式
,用于获取当前路由的 动态路径参数,适用于从 URL 中提取动态部分。
键:
string
,路由配置中定义的参数名如:id
。值:
string|string[]
,参数值,数组形式仅在使用重复参数如:chapters*
时出现。语法:
- 组合式API:
ts// 组合式 API 中通过 useRoute() 获取 import { useRoute } from 'vue-router'; const route = useRoute(); const params: Record<string, string|string[]> = route.params;
- 选项式API:
ts// 选项式 API 中通过 this.$route 访问 export default { computed: { routeParams() { return this.$route.params; } } }
特性:
基础动态参数:
ts// 路由配置:{ path: '/user/:id' } // 访问 URL:/user/123 console.log(route.params); // 输出:{ id: '123' }
多段动态参数:
ts// 路由配置:{ path: '/category/:type/:id' } // 访问 URL:/category/book/456 console.log(route.params); // 输出:{ type: 'book', id: '456' }
重复参数:数组形式,使用
*
或+
匹配多个路径段。ts// 路由配置:{ path: '/files/:files*' } // 访问 URL:/files/src/views/home.vue console.log(route.params); // 输出:{ files: ['src', 'views', 'home.vue'] }
可选参数:使用
?
定义可选参数。ts// 路由配置:{ path: '/user/:id?' } // 访问 URL:/user → params: { id: undefined } // 访问 URL:/user/789 → params: { id: '789' }
常见用途:
动态渲染内容:
html<template> <div v-if="route.params.id"> 用户ID:{{ route.params.id }} </div> </template> <script setup> import { useRoute } from 'vue-router'; const route = useRoute(); </script>
嵌套路由参数:父路由和子路由参数会合并。
js// 父路由配置 { path: '/parent/:parentId', children: [ { path: 'child/:childId' } ]} // 访问 URL:/parent/111/child/222 console.log(route.params); // { parentId: '111', childId: '222' }
监听参数变化:
jsimport { watch } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); watch( () => route.params.id, (newId) => { if (newId) fetchUserData(newId); } );
注意事项:
参数类型强制为字符串:即使 URL 中的参数是数字,params 也会返回字符串。
只读属性:修改 params 对象不会触发路由跳转,必须通过 router.push() 或 router-link。
未匹配参数的处理:访问未定义的参数返回 undefined,需防御性访问。
tsconst category = route.params.category || 'default';
对比route.query:
- params:来自路径的动态片段如
/user/123
。 - query:来自 URL 查询参数如
?search=vue
。
- params:来自路径的动态片段如
query
route.query:Record<string, string|string[]>
,只读
,响应式
,用于获取当前路由的 查询参数。
键:
string
,查询参数的键名。值:
string|string[]
,参数值,数组形式仅在同一个键多次出现时存在,如?tag=vue&tag=router
。语法:
- 组合式API:
ts// 组合式 API 中通过 useRoute() 获取 import { useRoute } from 'vue-router'; const route = useRoute(); const query: Record<string, string | string[]> = route.query;
- 选项式API:
ts// 选项式 API 中通过 this.$route 访问 export default { computed: { routeQuery() { return this.$route.query; } } }
特性:
查询参数解析规则:
- 单值参数:
ts// URL:/search?q=vue console.log(route.query.q); // 输出:'vue'
- 多值参数:数组形式
ts// URL:/filter?tag=vue&tag=router console.log(route.query.tag); // 输出:['vue', 'router']
- 未定义参数:访问不存在的参数返回 undefined。
ts// URL:/user?id=123 console.log(route.query.name); // 输出:undefined
- 空值参数:
ts// URL:/config?debug= console.log(route.query.debug); // 输出:''
常见用途:
动态渲染基于查询参数的内容:
html<template> <div v-if="route.query.search"> 搜索关键词:{{ route.query.search }} </div> </template> <script setup> import { useRoute } from 'vue-router'; const route = useRoute(); </script>
监听查询参数变化:
jsimport { watch } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); watch( () => route.query.page, (newPage) => { if (newPage) loadData(parseInt(newPage)); } );
编程式导航更新查询参数:
js// 添加或修改参数(保留其他参数) router.push({ query: { ...route.query, sort: 'price' } }); // 移除参数(排除指定键) const { sort, ...restQuery } = route.query; router.push({ query: restQuery });
注意事项:
- 参数类型强制为字符串:即使 URL 中的参数是数字,query 也会返回字符串。
- 编码与解码:特殊字符如空格、&,会被自动编码和解码。
- 避免直接修改:修改 route.query 对象不会触发路由跳转,必须通过 router.push()。
hash
route.hash:string
,只读
,响应式
,用于获取当前路由的 哈希值。常用于页面内锚点导航或状态标记。
语法:
- 组合式API:
ts// 组合式 API 中通过 useRoute() 获取 import { useRoute } from 'vue-router'; const route = useRoute(); const hash: string = route.hash;
- 选项式API:
ts// 选项式 API 中通过 this.$route 访问 export default { computed: { currentHash() { return this.$route.hash; } } }
特性:
- 无哈希时:返回空字符串
''
,而非 undefined 或 null。 - SSR:在 SSR 中,哈希值仅在客户端有效,服务端无法获取。
- 无哈希时:返回空字符串
常见用途:
哈希驱动的锚点导航:通过哈希跳转到页面内的指定元素,需要元素有 id 匹配。
js<!-- 跳转到 id="section2" 的元素 --> <a href="#section2">跳转到第二节</a> <!-- 目标元素 --> <section id="section2">...</section>
编程式导航修改哈希:
js// 添加或更新哈希 router.push({ hash: '#settings' }); // 移除哈希 router.push({ hash: '' }); // 或 router.push({ path: route.path, query: route.query });
监听哈希变化:
jsimport { watch } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); watch( () => route.hash, (newHash) => { if (newHash === '#comments') loadComments(); } );
根据哈希动态渲染内容:
html<template> <div v-if="route.hash === '#edit'"> <EditForm /> </div> <div v-else-if="route.hash === '#preview'"> <PreviewSection /> </div> </template> <script setup> import { useRoute } from 'vue-router'; const route = useRoute(); </script>
导航守卫中拦截哈希:
tsrouter.beforeEach((to) => { if (to.hash === '#admin' && !isAdmin) { return '/login'; } });
平滑滚动到锚点:
tsconst scrollToHash = () => { if (route.hash) { const target = document.querySelector(route.hash); if (target) target.scrollIntoView({ behavior: 'smooth' }); } };
注意事项:
哈希与浏览器历史记录:修改哈希会将新记录推入浏览器历史栈,可通过 router.replace() 避免。
tsrouter.replace({ hash: '#top' }); // 替换当前历史记录
编码与解码:特殊字符如空格,会被自动编码和解码。
matched
route.matched:RouteRecordNormalized[]
,只读
,响应式
,返回一个包含 当前路由匹配的所有嵌套路由记录 的数组。适用于访问嵌套路由的元数据、路径等信息。
语法:
- 组合式API:
ts// 组合式 API 中通过 useRoute() 获取 import { useRoute } from 'vue-router'; const route = useRoute(); const matched: RouteRecordNormalized[] = route.matched;
- 选项式API:
ts// 选项式 API 中通过 this.$route 访问 export default { computed: { matchedRoutes() { return this.$route.matched; } } }
特性:
顺序:数组按嵌套层级从父到子排列,如
[父路由记录, 子路由记录]
。嵌套路由匹配:
ts// 路由配置: const routes = [ { path: '/parent', component: Parent, children: [ { path: 'child', component: Child } ] } ]; // 访问 URL:/parent/child console.log(route.matched); // 输出: // [ // { path: '/parent', ... }, // 父路由记录 // { path: 'child', ... } // 子路由记录 // ]
访问元数据meta:常用于权限控制或面包屑导航
ts// 路由配置: { path: '/admin', meta: { requiresAuth: true }, children: [ { path: 'dashboard', meta: { title: '控制台' } } ] } // 在组件中检查权限: const requiresAuth = route.matched.some(record => record.meta.requiresAuth);
处理别名和重定向:即使路由通过别名或重定向匹配,route.matched 仍反映实际匹配的原始记录。
ts// 路由配置: { path: '/home', alias: '/welcome' } // 访问 URL:/welcome console.log(route.matched[0].path); // 输出 "/home"
常见用途:
生成面包屑导航:
html<template> <nav> <span v-for="(record, index) in route.matched" :key="index"> <a :href="record.path">{{ record.meta.title }}</a> <span v-if="index < route.matched.length - 1"> / </span> </span> </nav> </template> <script setup> import { useRoute } from 'vue-router'; const route = useRoute(); </script>
全局导航守卫中检查路由元数据:
jsrouter.beforeEach((to) => { const requiresAuth = to.matched.some(record => record.meta.requiresAuth); if (requiresAuth && !isLoggedIn) return '/login'; });
获取当前路由的所有组件:
jsconst components = route.matched.flatMap(record => Object.values(record.components) );
注意事项:
- 空匹配数组:若当前路由未匹配任何配置如 404,route.matched 为空数组。
- 路由记录标准化:RouteRecordNormalized 是 Vue Router 内部处理后的配置,可能与用户定义的路由配置略有不同。
SSR
createMemoryHistory()
createMemoryHistory():()
,用于创建一个基于 内存 的路由历史记录,也称为“抽象模式”。
base?:
string
,默认:''
,表示应用的基础路径,所有路由将相对于该路径解析。返回:
history:
RouterHistory
,返回一个RouterHistory对象,用于 Vue Router 的配置。语法:
base规范化:
- 自动添加前导斜杠,如
my-app
→/my-app
。 - 尾部斜杠会被保留,如传入
/my-app/
则保持为/my-app/
。
- 自动添加前导斜杠,如
base设置路由前缀:部署时可以通过base设置路由前缀,如
/my-app/
。自定义初始状态:可通过选项对象初始化内存历史记录的初始路径和状态。
jsconst history = createMemoryHistory({ base: '/my-app/', initialEntries: ['/home'], // 初始路径 initialState: { user: 'admin' } // 附加初始状态(可通过 router.currentRoute.value.state 访问) })
特性:
- 内存模式特点:
- 无URL依赖:路由状态完全存储在内存中,不修改浏览器 URL,适合无 DOM 的环境如 Node.js。
- 手动导航控制:需通过编程式导航,如
router.push()
或router.replace()
管理路由跳转。 - SSR友好:服务端渲染时,每个请求需创建一个独立的内存历史实例,避免状态污染。
- 轻量且隔离:不同实例之间的路由状态互不影响,适合多用户并发场景。
- 内存模式特点:
常见用途:
基本配置:
jsimport { createRouter, createMemoryHistory } from 'vue-router' const router = createRouter({ history: createMemoryHistory('/my-app/'), // 基础路径为 /my-app/ routes: [ { path: '/', component: Home }, { path: '/about', component: About } ] })
在SSR中的应用:
js// 服务端代码(Node.js) export function createSSRRouter() { return createRouter({ history: createMemoryHistory(), routes: [ // 定义路由... ] }) }
测试环境中模拟路由:
js// 单元测试示例(Jest/Vitest) test('navigates to about page', async () => { const history = createMemoryHistory() const router = createRouter({ history, routes }) await router.push('/about') expect(router.currentRoute.value.path).toBe('/about') })
注意事项:
- 不适用于浏览器环境:在浏览器中使用时,用户无法通过地址栏直接输入路径或使用前进/后退按钮导航。
- 需手动同步状态:若需要将路由状态传递到客户端,如 SSR 脱水/注水,需显式处理序列化和反序列化。