border-left: 7px solid currentColor;
}
+a.cta.rulekit {
+ font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
+}
+
+a.cta.rulekit::before {
+ content: '';
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ background-image: url('/rulekit-logo.svg');
+ background-size: 16px;
+ background-repeat: no-repeat;
+ background-position: center;
+ margin-right: 0.5em;
+ vertical-align: middle;
+ filter: brightness(0); /* Make it black by default */
+}
+
+html.dark a.cta.rulekit::before {
+ filter: brightness(0) invert(1); /* Make it white in dark mode */
+}
+
@media (max-width: 420px) {
a.cta.cta.vue-mastery {
max-width: 320px;
The `route` object is a reactive object. In most scenarios, you should **avoid watching the whole `route`** object. Instead, you can directly watch the properties you are expecting to change:
+<RuleKitLink />
+
```vue
<script setup>
import { useRoute } from 'vue-router'
# Data Fetching
+<RuleKitLink />
+
Sometimes you need to fetch data from the server when a route is activated. For example, before rendering a user profile, you need to fetch the user's data from the server. We can achieve this in two different ways:
- **Fetching After Navigation**: perform the navigation first, and fetch data in the incoming component's lifecycle hook. Display a loading state while data is being fetched.
Remember you can `await router.replace()` if you need to wait for the new route to be displayed.
+<RuleKitLink />
+
## Adding routes inside navigation guards
If you decide to add or remove routes inside of a navigation guard, you should not call `router.replace()` but trigger a redirection by returning the new location:
}
```
+<RuleKitLink />
+
In practice, you might want to use your `AppLink` component for different parts of your application. e.g. using [Tailwind CSS](https://tailwindcss.com), you could create a `NavLink.vue` component with all the classes:
```vue
The `component` (and `components`) option accepts a function that returns a Promise of a component and Vue Router **will only fetch it when entering the page for the first time**, then use the cached version. Which means you can also have more complex functions as long as they return a Promise:
+<RuleKitLink />
+
```js
const UserDetails = () =>
Promise.resolve({
})
```
+<RuleKitLink />
+
## TypeScript
It is possible to type the meta field by extending the `RouteMeta` interface from `vue-router`:
If a navigation is prevented, resulting in the user staying on the same page, the resolved value of the `Promise` returned by `router.push` will be a _Navigation Failure_. Otherwise, it will be a _falsy_ value (usually `undefined`). This allows us to differentiate the case where we navigated away from where we are or not:
+<RuleKitLink />
+
```js
const navigationResult = await router.push('/my-profile')
title="Learn how to add navigation guards"
/>
+<RuleKitLink />
+
As the name suggests, the navigation guards provided by Vue router are primarily used to guard navigations either by redirecting it or canceling it. There are a number of ways to hook into the route navigation process: globally, per-route, or in-component.
## Global Before Guards
# RouterView slot
+<RuleKitLink />
+
The RouterView component exposes a slot that can be used to render the route component:
```vue-html
The `scrollBehavior` function receives the `to` and `from` route objects, like [Navigation Guards](./navigation-guards.md). The third argument, `savedPosition`, is only available if this is a `popstate` navigation (triggered by the browser's back/forward buttons).
+<RuleKitLink />
+
The function can return a [`ScrollToOptions`](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions) position object:
```js
</router-view>
```
+<RuleKitLink />
+
## Route-Based Dynamic Transition
It is also possible to determine the transition to use dynamically based on the relationship between the target route and current route. Using a very similar snippet to the one just before:
# Typed Routes <Badge type="tip" text="v4.4.0+" />
+<RuleKitLink />
+

It's possible to configure the router to have a _map_ of typed routes. While this can be done manually, it is recommended to use the [unplugin-vue-router](https://github.com/posva/unplugin-vue-router) plugin to generate the routes and the types automatically.
If the current location path is `/user/erina/role/admin` then these would both be considered _active_, so the class `router-link-active` would be applied to both links. But only the second link would be considered _exact_, so only that second link would have the class `router-link-exact-active`.
+<RuleKitLink />
+
## Configuring the classes
The RouterLink component has two props, `activeClass` and `exactActiveClass`, that can be used to change the names of the classes that are applied:
If you are using [History mode](./history-mode.md), make sure to follow the instructions to correctly configure your server as well.
+<RuleKitLink />
+
## Advanced Matching Patterns
Vue Router uses its own path matching syntax, inspired by the one used by `express`, so it supports many advanced matching patterns such as optional params, zero or more / one or more requirements, and even custom regex patterns. Please check the [Advanced Matching](./route-matching-syntax.md) documentation to explore them.
}
```
+<RuleKitLink />
+
## Caveat
There is a caveat to this: Your server will no longer report 404 errors as all not-found paths now serve up your `index.html` file. To get around the issue, you should implement a catch-all route within your Vue app to show a 404 page:
- Avoids URL typos.
- Bypassing path ranking, e.g. to display a lower-ranked route that matches the same path.
+<RuleKitLink />
+
Each name **must be unique** across all routes. If you add the same name to multiple routes, the router will only keep the last one. You can read more about this [in the Dynamic Routing](../advanced/dynamic-routing#Removing-routes) section.
There are various other parts of Vue Router that can be passed a location, e.g. the methods `router.push()` and `router.replace()`. We'll go into more detail about those methods in the guide to [programmatic navigation](./navigation). Just like the `to` prop, these methods also support passing a location by `name`:
```
A working demo of this example can be found [here](https://codesandbox.io/s/nested-named-views-vue-router-4-examples-re9yl?&initialpath=%2Fsettings%2Femails).
+
+<RuleKitLink />
Therefore, if you are already familiar with [Browser History APIs](https://developer.mozilla.org/en-US/docs/Web/API/History_API), manipulating history will feel familiar when using Vue Router.
It is worth mentioning that Vue Router navigation methods (`push`, `replace`, `go`) work consistently no matter the `history` option passed when creating the router instance.
+
+<RuleKitLink />
A working demo of this example can be found [here](https://codesandbox.io/s/nested-views-vue-router-4-examples-hl326?initialpath=%2Fusers%2Feduardo).
+<RuleKitLink />
+
## Nested Named Routes
When dealing with [Named Routes](./named-routes.md), you usually **name the children routes**:
::: warning
In this case, **all view components** will receive `view-prop`. This is usually not a good idea as it means that all of the view components have declared a `view-prop` prop, which is not necessarily true. If possible, use any of the options above.
:::
+
+<RuleKitLink />
```
**Note about SEO**: when using aliases, make sure to [define canonical links](https://support.google.com/webmasters/answer/139066?hl=en).
+
+<RuleKitLink />
If you need to dig how your routes are transformed into a regex to understand why a route isn't being matched or, to report a bug, you can use the [path ranker tool](https://paths.esm.dev/?p=AAMeJSyAwR4UbFDAFxAcAGAIJXMAAA..#). It supports sharing your routes through the URL.
+<RuleKitLink />
+
## Avoiding slow regex
When using custom regex, make sure to avoid using slow regex patterns. For example, using `.*` will match any character and can lead to **serious performance issues** if it's combined with a repeatable modifier `*` or `+` and anything after it:
Vue Router is built on Vue's component system. You configure **routes** to tell Vue Router which components to show for each URL path.
-::: tip Prerequisites
This guide will assume that you are already familiar with Vue itself. You don't need to be a Vue expert, but you may occasionally need to refer back to [the core Vue documentation](https://vuejs.org/) for more information about certain features.
-:::
<RuleKitLink />
# Migrating from Vue 2
+<RuleKitLink />
+
Most of Vue Router API has remained unchanged during its rewrite from v3 (for Vue 2) to v4 (for Vue 3) but there are still a few breaking changes that you might encounter while migrating your application. This guide is here to help you understand why these changes happened and how to adapt your application to make it work with Vue Router 4.
## Breaking Changes
- theme: brand
text: Get Started
link: /installation
+ - theme: cta rulekit
+ text: RuleKit
+ link: https://rulekit.dev?from=vuerouter
- theme: cta vueschool
text: Free Video Course
link: https://vueschool.io/courses/vue-router-4-for-everyone?friend=vuerouter&utm_source=vuerouter&utm_medium=link&utm_campaign=homepage
<!--/email_off-->
This will expose Vue Router via a global `VueRouter` object, e.g. `VueRouter.createRouter(...)`.
+
+<RuleKitLink />
- Customizable Scroll Behavior
- Proper encoding for URLs
+<RuleKitLink />
+
[Get started](./guide/) or play with the [playground](https://github.com/vuejs/router/tree/main/packages/playground) (see [`README.md`](https://github.com/vuejs/router) to run them).
<HomeSponsors />
--- /dev/null
+<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M335 694L353.947 697.225V737L335 733.775V694Z" fill="currentColor"/>
+ <path d="M355 538.234V673L335 669.766V536.078L355 538.234Z" fill="currentColor"/>
+ <path d="M259.255 329.5L313.424 338.585V414.78L374.576 425.512V350.39L422.5 359.457L422.529 391.816L399.251 388.374V443.756L375.649 440.537V460.314L313.424 449.576V430.878L287.675 426.585L286.602 367.561L259.255 364V329.5Z" fill="currentColor"/>
+ <path d="M398.897 113.5L647.031 158.597V199L676.034 205.5V276L836.085 304.623L896.239 362.605V498.968L873.681 516.147V778.5L914.5 792.095L755.522 914.5L180.84 802.832L130.354 738.409V472.125L103.5 457.092V336.835L164.728 270.264L291.48 205.5L321.557 211V176.85L350.56 165.5V139L398.897 113.5ZM379.562 148.933V184L350.56 182.218L349.485 259.527L379.562 263.822V184L582.581 218.725V300.328L622.325 307V224.094L598.693 220.873V188.661L379.562 148.933ZM433.271 218.725V234.831L561.097 257.379V240.2L433.271 218.725ZM291.48 234.831L223.807 272.412L740.484 364.752L802.786 325.024L673.885 302.476L622.325 330L561.097 319V282L433.271 259.527L389.23 285.296L321.557 275V240.2L291.48 234.831ZM180.84 288.517L128.206 343.277V440.537L233.475 461.387L232.401 360.457L259.255 364V446L284.103 449.576V476.42L311.889 480.714V750L373.117 762L374.191 691.165V493.599L399.251 497V472.125L422.5 476.42L422.529 391.816L449.383 396.964V500L543.911 516V414.143L571.839 418.438V388.374L624.474 396.964V423.807L652.402 428V534.5L778.08 551.5V443.756L731 392.244L180.84 288.517ZM831.789 336.835L757.671 383.005L796.341 423.807L871.533 374.416L831.789 336.835ZM807.083 445.281V529.032L871.533 486.083V404.48L807.083 445.281ZM571.839 449.576V521.516L587 524.5V592L606.213 595.603V527.5L624.474 531V458.5L571.839 449.576ZM155.06 472.125V729.5L191.5 778.5L713 880.5L754.448 853.298V579.497L635.215 560.17V601L682.479 609.562V649.29L663.144 647V682.575L682.479 684.723L683.5 814.5L652.402 808.201V839L543.911 819.5V788.874L511.685 783.505V654.5L532.095 658.5V623.52L511.685 620.299V578.424L557.875 585.94V545.138L422.5 521.516L402.12 538.234V654.658V766.326L373.117 762V791.021L311.889 778.5V750L285.035 744.851V512.926L264.5 493.599L155.06 472.125ZM778.08 579.497L780.228 833.971L847.901 781.358V538.234L778.08 579.497ZM561.097 627.5V664.5L543.911 661V788.874L565.394 793.169L567 669L584.729 672V632.5L561.097 627.5ZM611.583 639.626V676.5L628.77 679V802.832L652.402 808.201V682.575L635.215 680.428V643L611.583 639.626Z" fill="currentColor"/>
+</svg>
\ No newline at end of file
# 关于中文翻译
+<RuleKitLink />
+
这里是 Vue Router 文档的中文翻译,该翻译由 Vue 社区贡献完成,如对翻译有任何疑问,可在我们的 GitHub 仓库创建 issue 或 pull request。谢谢。
## 协作指南
`route` 对象是一个响应式对象。在多数情况下,你应该**避免监听整个 `route`** 对象,同时直接监听你期望改变的参数。
+<RuleKitLink />
+
```vue
<script setup>
import { useRoute } from 'vue-router'
# 数据获取
+<RuleKitLink />
+
有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:
- **导航完成之后获取**:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
记住,如果你需要等待新的路由显示,可以使用 `await router.replace()`。
+<RuleKitLink />
+
## 在导航守卫中添加路由
如果你决定在导航守卫内部添加或删除路由,你不应该调用 `router.replace()`,而是通过返回新的位置来触发重定向:
}
```
+<RuleKitLink />
+
在实践中,你可能希望将你的 `AppLink` 组件用于应用程序的不同部分。例如,使用 [Tailwind CSS](https://tailwindcss.com),你可以用所有的类创建一个 `NavLink.vue` 组件:
```vue
`component` (和 `components`) 配置接收一个返回 Promise 组件的函数,Vue Router **只会在第一次进入页面时才会获取这个函数**,然后使用缓存数据。这意味着你也可以使用更复杂的函数,只要它们返回一个 Promise :
+<RuleKitLink />
+
```js
const UserDetails = () =>
Promise.resolve({
})
```
+<RuleKitLink />
+
## TypeScript
也可以继承来自 `vue-router` 中的 `RouteMeta` 来为 meta 字段添加类型:
如果导航被阻止,导致用户停留在同一个页面上,由 `router.push` 返回的 `Promise` 的解析值将是 _Navigation Failure_。否则,它将是一个 _falsy_ 值(通常是 `undefined`)。这样我们就可以区分我们导航是否离开了当前位置:
+<RuleKitLink />
+
```js
const navigationResult = await router.push('/my-profile')
title="Learn how to add navigation guards"
/>
+<RuleKitLink />
+
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
## 全局前置守卫
# RouterView 插槽
+<RuleKitLink />
+
RouterView 组件暴露了一个插槽,可以用来渲染路由组件:
```vue-html
`scrollBehavior` 函数接收 `to`和`from` 路由对象,如 [Navigation Guards](./navigation-guards.md)。第三个参数 `savedPosition`,只有当这是一个 `popstate` 导航时才可用(由浏览器的后退/前进按钮触发)。
+<RuleKitLink />
+
该函数可以返回一个 [`ScrollToOptions`](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions) 位置对象:
```js
</router-view>
```
+<RuleKitLink />
+
## 基于路由的动态过渡
也可以根据目标路由和当前路由之间的关系,动态地确定使用的过渡。使用和刚才非常相似的片段:
# 类型化路由 (v4.1.0+)
+<RuleKitLink />
+
::: danger ‼️ 实验性功能
从 v4.1.0 开始,我们引入一个新的功能,称为类型化路由。这个**实验性**功能通过 Vite/webpack/Rollup 插件启用。
如果当前路径是 `/user/erina/role/admin`,那么这两个链接都会被认为是**匹配当前路由的**,因此 `router-link-active` 类会应用于这两个链接。但只有第二个链接会被认为是**精确的**,因此只有第二个链接会有 `router-link-exact-active` 类。
+<RuleKitLink />
+
## 配置类名
RouterLink 组件有两个属性,`activeClass` 和 `exactActiveClass`,可以用来更改应用的类名:
如果你正在使用[历史模式](./history-mode.md),请务必按照说明正确配置你的服务器。
+<RuleKitLink />
+
## 高级匹配模式
Vue Router 使用自己的路径匹配语法,其灵感来自于 `express`,因此它支持许多高级匹配模式,如可选的参数,零或多个 / 一个或多个,甚至自定义的正则匹配规则。请查看[高级匹配](./route-matching-syntax.md)文档来探索它们。
}
```
+<RuleKitLink />
+
## 附加说明
这有一个注意事项。你的服务器将不再报告 404 错误,因为现在所有未找到的路径都会显示你的 `index.html` 文件。为了解决这个问题,你应该在你的 Vue 应用程序中实现一个万能的路由来显示 404 页面。
- 防止你在 URL 中出现打字错误。
- 绕过路径排序,例如展示一个匹配相同路径但排序较低的路由。
+<RuleKitLink />
+
所有路由的命名**都必须是唯一的**。如果为多条路由添加相同的命名,路由器只会保留最后那一条。你可以在[动态路由](../advanced/dynamic-routing.md#Removing-routes)章节了解更多。
Vue Router 有很多其他部分可以传入网址,例如 `router.push()` 和 `router.replace()` 方法。我们将在[编程式导航](./navigation.md)指南中详细介绍这些方法。就像 `to` 属性一样,这些方法也支持通过 `name` 传入网址:
```
以上案例相关的可运行代码请[移步这里](https://codesandbox.io/s/nested-named-views-vue-router-4-examples-re9yl?&initialpath=%2Fsettings%2Femails).
+
+<RuleKitLink />
因此,如果你已经熟悉 [Browser History APIs](https://developer.mozilla.org/en-US/docs/Web/API/History_API),在使用 Vue Router 时,操作历史记录就会觉得很熟悉。
值得一提的是,无论在创建路由器实例时传递什么 `history` 配置,Vue Router 的导航方法 (`push`、`replace`、`go`) 都能始终正常工作。
+
+<RuleKitLink />
这个例子的 demo 可以在[这里](https://codesandbox.io/s/nested-views-vue-router-4-examples-hl326?initialpath=%2Fusers%2Feduardo)找到。
+<RuleKitLink />
+
## 嵌套的命名路由
在处理[命名路由](./named-routes.md)时,**你通常会给子路由命名**:
::: warning
在这种情况下,**所有视图组件**都会接收到 `view-prop`。通常这并不是一个好主意,因为这意味着所有的视图组件都声明了一个 `view-prop` prop,但这未必需要。所以请尽可能使用上述的其他选项。
:::
+
+<RuleKitLink />
```
**关于 SEO 的注意事项**: 使用别名时,一定要[定义规范链接](https://support.google.com/webmasters/answer/139066?hl=en).
+
+<RuleKitLink />
## 调试
如果你需要探究你的路由是如何转化为正则的,以了解为什么一个路由没有被匹配,或者,报告一个 bug,你可以使用[路径排名工具](https://paths.esm.dev/?p=AAMeJSyAwR4UbFDAFxAcAGAIJXMAAA..#)。它支持通过 URL 分享你的路由。
+
+<RuleKitLink />
# 从 Vue2 迁移
+<RuleKitLink />
+
在 Vue Router API 从 v3(Vue2)到 v4(Vue3)的重写过程中,大部分的 Vue Router API 都没有变化,但是在迁移你的程序时,你可能会遇到一些破坏性的变化。本指南将帮助你了解为什么会发生这些变化,以及如何调整你的程序,使其与 Vue Router4 兼容。
## 破坏性变化
- theme: brand
text: 入门 →
link: /zh/introduction
+ - theme: cta rulekit
+ text: RuleKit
+ link: https://rulekit.dev?from=vuerouter
- theme: cta vueschool
text: 免费视频课程
link: https://vueschool.io/courses/vue-router-4-for-everyone?friend=vuerouter&utm_source=vuerouter&utm_medium=link&utm_campaign=homepage
这将把 Vue Router 暴露在一个全局的 `VueRouter` 对象上,例如 `VueRouter.createRouter(...)`。
+<RuleKitLink />
+
- 可定制的滚动行为
- URL 的正确编码
+<RuleKitLink />
+
[入门](./guide/)或使用 [playground](https://github.com/vuejs/router/tree/main/packages/playground) (详见[`README.md`](https://github.com/vuejs/router)来运行它们)。
<HomeSponsors />