Vue Router API 参考:常用方法与属性详解
Vue Router API 参考:常用方法与属性详解
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用 (SPA) 变得易如反掌。本文将深入探讨 Vue Router 的常用 API,包括方法和属性,并通过示例代码进行详细讲解,帮助你全面掌握 Vue Router 的使用。
一、核心概念回顾
在深入 API 之前,让我们快速回顾几个 Vue Router 的核心概念:
- 路由 (Route):一个路由就是一个 URL 路径与一个 Vue 组件之间的映射关系。例如,
/home
映射到Home
组件,/about
映射到About
组件。 - 路由器 (Router):路由器负责管理所有的路由,监听 URL 变化,并根据路由配置渲染相应的组件。
- 路由配置 (Router Configuration):一个 JavaScript 对象,定义了所有路由的映射关系、导航守卫、滚动行为等。
- 路由出口 (Router View):
<router-view>
组件,用于在父组件中渲染当前路由匹配到的子组件。 - 路由链接 (Router Link):
<router-link>
组件,用于创建导航链接,用户点击后会触发路由跳转,而不会导致整个页面刷新。
二、$router
对象(路由器实例)
$router
对象是 Vue Router 的路由器实例,它可以在任何 Vue 组件中通过 this.$router
访问。$router
对象提供了许多方法和属性,用于编程式导航、访问路由信息等。
2.1 常用方法
2.1.1 push(location, onComplete?, onAbort?)
- 功能:以编程方式导航到一个新的 URL。类似于
history.pushState
,它会在浏览器的历史记录中添加一条新记录。 - 参数:
location
: 目标路由。可以是一个字符串路径,也可以是一个描述路由的对象(包含path
、name
、params
、query
等属性)。onComplete
: 可选的回调函数,当导航成功完成时调用。onAbort
: 可选的回调函数,当导航被中断(例如,被导航守卫阻止)时调用。
- 返回值: 一个
Promise
对象(如果支持 Promise),解析为成功或失败。 -
示例:
```javascript
// 字符串路径
this.$router.push('/home');// 带有路径的对象
this.$router.push({ path: '/user/123' });// 命名的路由 (推荐)
this.$router.push({ name: 'user', params: { userId: 123 } });// 带查询参数
this.$router.push({ path: '/products', query: { sort: 'price' } });// 使用回调
this.$router.push('/profile', () => {
console.log('导航完成');
}, (err) => {
console.error('导航失败', err);
});//Promise
this.$router.push('/login')
.then(() => {
//导航成功
}).catch(err => {
//失败的处理
});
```
2.1.2 replace(location, onComplete?, onAbort?)
- 功能:与
push
类似,但它会替换当前的历史记录条目,而不是添加新的条目。类似于history.replaceState
。 - 参数:与
push
相同。 - 返回值: 一个
Promise
对象(如果支持 Promise),解析为成功或失败。 -
示例:
javascript
this.$router.replace({ name: 'login' });
2.1.3 go(n)
- 功能:在浏览器的历史记录中前进或后退
n
步。类似于history.go(n)
。 - 参数:
n
: 整数,表示要前进(正数)或后退(负数)的步数。
-
示例:
```javascript
// 后退一页
this.$router.go(-1);// 前进一页
this.$router.go(1);// 前进两页
this.$router.go(2);
```
2.1.4 back()
- 功能:后退一页。等同于
this.$router.go(-1)
。 -
示例:
javascript
this.$router.back();
2.1.5 forward()
- 功能:前进一页。等同于
this.$router.go(1)
。 -
示例:
javascript
this.$router.forward();
2.1.6 addRoute(route, parent?)
- 功能: 动态添加一个新的路由。
- 参数:
route
: 一个符合路由配置格式的对象。parent?
(可选): 父路由的名称或路径。如果提供,新路由将作为该父路由的子路由。
- 返回值: 一个函数,调用该函数可以删除添加的路由。
-
示例:
```javascript
const removeRoute = this.$router.addRoute({
path: '/new-route',
name: 'NewRoute',
component: NewRouteComponent
});// 移除添加的路由
removeRoute();// 添加子路由
this.$router.addRoute({
path: '/parent',
name: 'Parent',
component: ParentComponent
}, { path: 'child', name: 'Child', component: ChildComponent });
```
2.1.7 removeRoute(name)
- 功能: 根据路由名称移除一个已存在的路由。
- 参数:
name
: 要移除的路由的名称。
- 示例:
javascript
this.$router.removeRoute('NewRoute'); // 移除名为 'NewRoute' 的路由
2.1.8 hasRoute(name)
- 功能:检查是否存在指定名称的路由
- 参数:
name
: 要检查的路由的名称
- 返回值:
boolean
- 示例:
javascript
if (this.$router.hasRoute('User')) {
//路由'User' 存在
}
2.1.9 getRoutes()
- 功能: 获取当前所有激活的路由记录的列表。
- 返回值:
Array<RouteRecord>
- 示例:
javascript
const routes = this.$router.getRoutes();
console.log(routes); //输出当前所有路由信息
2.2 常用属性
2.2.1 currentRoute
- 类型:
Route
对象 (响应式) - 功能:表示当前激活的路由信息。它是一个响应式对象,当路由变化时,依赖于它的组件会重新渲染。
- 包含的属性:
path
: 当前路由的完整路径(例如,/user/123?name=john
)。name
: 路由的名称(如果有)。params
: 路由参数对象(例如,{ userId: 123 }
)。query
: 查询参数对象(例如,{ name: 'john' }
)。hash
: URL 的哈希部分(例如,#section1
)。fullPath
: 完整的解析后的 URL,包含查询参数和哈希(例如,/user/123?name=john#section1
)。matched
: 一个数组,包含当前路由匹配到的所有路由记录(从父到子)。meta
: 路由元信息对象(如果有)。redirectedFrom
: 如果当前路由是被重定向来的,则该属性包含原始路由的信息.
-
示例:
vue
<template>
<div>
<p>当前路径:{{ $router.currentRoute.path }}</p>
<p>用户 ID:{{ $router.currentRoute.params.userId }}</p>
<p>查询参数:{{ $router.currentRoute.query }}</p>
</div>
</template>
2.2.2 options
- 类型:
RouterOptions
- 功能: 返回传递给
new VueRouter()
构造函数的原始选项对象. 包含了routes
,mode
,base
等. - 示例:
javascript
console.log(this.$router.options); //输出创建路由器时传入的配置
2.2.3 app
- 类型:
Vue
- 功能: 当前的 Vue 根实例.
- 示例:
javascript
console.log(this.$router.app); //输出Vue 根实例
三、$route
对象 (当前路由信息)
$route
对象与 $router.currentRoute
相同,它也代表当前激活的路由信息。你可以在组件中通过 this.$route
访问它。$route
是响应式的,当路由变化时,依赖于它的组件会自动更新。
注意: this.$route
和 this.$router.currentRoute
是同一个对象的不同引用方式.
$route
对象的属性与 $router.currentRoute
完全一致,包括:path
、name
、params
、query
、hash
、fullPath
、matched
、meta
, redirectedFrom
。
示例:
```vue
当前路径:{{ $route.path }}
用户 ID:{{ $route.params.userId }}
查询参数:{{ $route.query }}
```
四、路由配置选项
在创建 Vue Router 实例时,我们需要提供一个配置对象。这个对象定义了路由的映射关系、导航守卫、滚动行为等。
4.1 routes
- 类型:
Array<RouteConfig>
- 功能:定义路由映射关系。每个
RouteConfig
对象描述一个路由。 -
RouteConfig
对象的属性:path
: 字符串,路由的路径。name
: 字符串,路由的名称(可选,但推荐使用,方便编程式导航)。component
: 组件,当路由匹配时要渲染的组件。可以是一个组件对象,也可以是一个返回组件的函数(用于代码分割)。components
: 对象,用于命名视图。当一个路由需要渲染多个组件时使用。redirect
: 字符串、对象或函数,重定向到另一个路由。props
: 布尔值、对象或函数,将路由参数作为 props 传递给组件。alias
: 字符串或数组,路由别名。children
: 数组,嵌套路由配置。meta
: 对象,路由元信息(自定义数据)。beforeEnter
: 导航守卫函数,只对当前路由生效。caseSensitive
: 布尔值, 匹配规则是否大小写敏感?(默认值:false)pathToRegexpOptions
: 编译正则的选项: 更多信息.
-
示例:
javascript
const routes = [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/about',
name: 'about',
component: () => import('./views/About.vue'), // 懒加载
},
{
path: '/user/:userId',
name: 'user',
component: User,
props: true, // 将 params 作为 props 传递给 User 组件
meta: { requiresAuth: true }, // 自定义元信息
},
{
path: '/posts/:postId',
components: {
default: Post,
sidebar: PostSidebar
}
},
{
path: '/login',
name: 'login',
component: Login,
beforeEnter: (to, from, next) => {
// 只对 /login 路由生效的守卫
if (isAuthenticated()) {
next('/'); // 如果已登录,重定向到首页
} else {
next(); // 允许访问 /login
}
},
},
{
path: '/parent',
component: Parent,
children: [
{
path: 'child1', //相对于 /parent
component: Child1
},
{
path: '/absolute-child', //绝对路径
component: AbsoluteChild
}
]
},
{
path: '/order',
redirect: '/order/pending' //重定向
},
{
path: '*', //通配符 * 匹配任何路径
component: NotFound
}
];
4.2 mode
- 类型:
string
- 可选值:
'history'
: 使用 HTML5 History API,需要服务器配置支持。'hash'
: 使用 URL 的哈希部分 (#
) 来模拟路由,不需要服务器配置。'abstract'
: 在非浏览器环境中使用 (例如 Node.js).
- 默认值:
'hash'
-
示例:
javascript
const router = new VueRouter({
mode: 'history', // 使用 history 模式
routes,
});
4.3 base
- 类型:
string
- 功能:应用的基路径。例如,如果整个单页应用服务在
/app/
下,那么base
就应该设为"/app/"
。 - 默认值:
'/'
-
示例:
javascript
const router = new VueRouter({
base: '/my-app/',
routes,
});
4.4 linkActiveClass
- 类型:
string
- 功能:全局配置
<router-link>
的默认激活 class。 - 默认值:
'router-link-active'
-
示例:
javascript
const router = new VueRouter({
linkActiveClass: 'active-link',
routes,
});
4.5 linkExactActiveClass
- 类型:
string
- 功能:全局配置
<router-link>
的精确激活 class(只有当 URL 与<router-link>
的to
属性完全匹配时才添加)。 - 默认值:
'router-link-exact-active'
- 示例:
javascript
const router = new VueRouter({
linkExactActiveClass: 'exact-active'
});
4.6 scrollBehavior
- 类型:
(to, from, savedPosition) => Position | { x: number, y: number } | { selector: string, offset?: { x: number, y: number } } | Promise<PositionResult>
- 功能:自定义路由切换时的滚动行为。
- 参数:
to
: 即将进入的目标路由对象。from
: 即将离开的源路由对象。savedPosition
: 仅当使用浏览器的前进/后退按钮时才可用,表示之前滚动的位置。
- 返回值:
{ x: number, y: number }
: 滚动到指定的坐标。{ selector: string, offset?: { x: number, y: number } }
: 滚动到指定的元素,可以使用offset
调整偏移量。Promise<PositionResult>
: 异步滚动.false
或 空对象: 不发生滚动.
-
示例:
```javascript
const router = new VueRouter({
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition; // 使用浏览器历史记录的滚动位置
} else if (to.hash) {
return { selector: to.hash }; // 滚动到锚点
} else {
return { x: 0, y: 0 }; // 滚动到页面顶部
}// 异步滚动 // return new Promise((resolve) => { // setTimeout(() => { // resolve({x: 0, y: 0}); // }, 500); // });
},
});
```
4.7 parseQuery / stringifyQuery
- 类型:
Function
- 功能: 自定义查询字符串的解析和序列化函数。
- 示例:
javascript
const router = new VueRouter({
parseQuery(query) {
// 自定义解析逻辑
},
stringifyQuery(query) {
//自定义序列化
}
})
4.8 fallback
- 类型:
boolean
- 功能: 当浏览器不支持
history.pushState
控制路由是否应该回退到hash
模式。默认值为true
。
在 IE9 中, 如果设置为false
,则在mode: 'history'
下,所有router-link
导航都会触发整页刷新。 - 示例:
javascript
const router = new VueRouter({
mode: 'history',
fallback: false //IE9 下禁用回退
});
五、导航守卫
导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
5.1 全局守卫
beforeEach(to, from, next)
:在每次导航前执行。beforeResolve(to, from, next)
:在每次导航前执行,但在beforeEach
之后,所有组件内守卫和异步路由组件被解析之后。-
afterEach(to, from)
:在每次导航完成后执行(没有next
参数)。```javascript
router.beforeEach((to, from, next) => {
// to: 即将进入的目标路由对象
// from: 即将离开的源路由对象
// next: 函数,必须调用,否则导航不会继续
// - next(): 继续导航
// - next(false): 中断导航
// - next('/login'): 重定向到 /login
// - next(new Error('...')): 抛出错误if (to.matched.some(record => record.meta.requiresAuth)) {
//判断是否需要登录权限
if (!isAuthenticated()) {
next({ name: 'Login', query: { redirect: to.fullPath } }) //未登录,跳转到登录页面
} else {
next(); //已经登录
}
}else {
next(); //确保一定要调用 next()
}
});router.beforeResolve((to, from, next) => {
//类似 beforeEach,区别是在所有组件内守卫和异步路由组件被解析之后
next();
});router.afterEach((to, from) => {
// to: 已经进入的目标路由对象
// from: 已经离开的源路由对象
console.log('导航完成', to, from);
//常用于埋点统计
});
```
5.2 路由独享守卫
-
beforeEnter(to, from, next)
:在单个路由配置中定义,只对该路由生效。javascript
const routes = [
{
path: '/profile',
component: Profile,
beforeEnter: (to, from, next) => {
// ...
},
},
];
5.3 组件内守卫
beforeRouteEnter(to, from, next)
:在渲染该组件的对应路由被 confirm 前调用。不能访问this
,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。beforeRouteUpdate(to, from, next)
:在当前路由改变,但是该组件被复用时调用。可以访问this
。-
beforeRouteLeave(to, from, next)
:导航离开该组件的对应路由时调用。可以访问this
。vue
<script>
export default {
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不能访问 `this`
next(vm => {
// 通过 `vm` 访问组件实例
console.log(vm);
});
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 可以访问 `this`
next();
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问 `this`
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
},
};
</script>
六、<router-link>
组件
<router-link>
是 Vue Router 提供的用于创建导航链接的组件。它会被渲染成一个 <a>
标签,但它会阻止浏览器的默认跳转行为,而是通过 Vue Router 来进行路由切换。
6.1 常用属性
to
:目标路由。可以是字符串路径,也可以是一个描述路由的对象。replace
:布尔值,如果设置为true
,则使用replace
方式导航,而不是push
。append
:布尔值,如果设置为true
,则在当前 (相对) 路径附加其路径。例如,我们从/a
导航到一个相对路径b
,如果没有配置append
,则路径为/b
,如果配了,则为/a/b
tag
:字符串,指定要渲染的标签,默认为'a'
。active-class
:字符串,当链接激活时应用的 class,默认为'router-link-active'
。exact
:布尔值,是否使用精确匹配模式。exact-active-class
:字符串,当链接精确激活时应用的 class,默认为'router-link-exact-active'
。event
: 字符串或数组, 声明可以触发导航的事件。默认是'click'
.-
aria-current-value
: 当链接根据路由匹配规则激活时要使用的 aria-current 的值。 -
示例:
vue
<router-link to="/">Home</router-link>
<router-link :to="{ name: 'user', params: { userId: 123 } }">User</router-link>
<router-link to="/about" replace>About</router-link>
<router-link to="/contact" tag="li">Contact</router-link>
<router-link to="/news" active-class="is-active">News</router-link>
<router-link to="/posts/123" exact>Post 123</router-link>
<router-link to="/events" :event="['mousedown', 'touchstart']">Events</router-link>
七、<router-view>
组件
<router-view>
是一个占位符,用于渲染当前路由匹配到的组件。
7.1 常用属性
name
:字符串, 如果<router-view>
设置了名称,则会渲染对应的路由配置中components
下的相应组件。-
示例:
```vue
javascript
//路由配置
{
path: '/posts/:postId',
components: { //注意是复数 components
default: Post,
sidebar: PostSidebar
}
}
```
八、总结
本文详细介绍了 Vue Router 的常用 API,包括 $router
对象的方法和属性、$route
对象、路由配置选项、导航守卫、<router-link>
组件和 <router-view>
组件。通过掌握这些 API,你可以灵活地控制路由、实现各种导航需求,构建功能强大的单页面应用。
希望这篇文章能够帮助你更好地理解和使用 Vue Router! 请记住,熟练掌握 Vue Router 的关键在于实践。多写代码,多尝试不同的配置和用法,你会越来越熟练。