rel="sponsored noopener"
:title="title"
>
- <slot>Watch a free video lesson on Vue School</slot>
+ <slot>{{ translations[site.lang]}}</slot>
</a>
</div>
</template>
-<script>
-export default {
- props: {
- href: { type: String, required: true },
- title: { type: String, required: true },
- },
+<script setup lang="ts">
+import { useData } from 'vitepress'
+
+const { site } = useData()
+const translations = {
+ 'en-US': 'Watch a free video lesson on Vue School',
+ 'zh-CN': '在 Vue School 上观看免费视频课程',
}
+defineProps<{ href: string; title: string }>()
</script>
<style scoped>
.vueschool {
- **Type**: `string`
- **Details**:
- Path of the record. Should start with `/` unless the record is the child of another record.
- Can define parameters: `/users/:id` matches `/users/1` as well as `/users/posva`.
+ Path of the record. Should start with `/` unless the record is the child of another record. Can define parameters: `/users/:id` matches `/users/1` as well as `/users/posva`.
- **See Also**: [Dynamic Route Matching](../guide/essentials/dynamic-matching.md)
- **Type**: `RouteLocationRaw | (to: RouteLocationNormalized) => RouteLocationRaw` (Optional)
- **Details**:
- Where to redirect if the route is directly matched. The redirection happens
- before any navigation guard and triggers a new navigation with the new target
- location. Can also be a function that receives the target route location and
- returns the location we should redirect to.
+ Where to redirect if the route is directly matched. The redirection happens before any navigation guard and triggers a new navigation with the new target location. Can also be a function that receives the target route location and returns the location we should redirect to.
### children
- **Type**: `string | string[]` (Optional)
- **Details**:
- Aliases for the route. Allows defining extra paths that will behave like a
- copy of the record. This enables paths shorthands like `/users/:id` and
- `/u/:id`. **All `alias` and `path` values must share the same params**.
+ Aliases for the route. Allows defining extra paths that will behave like a copy of the record. This enables paths shorthands like `/users/:id` and `/u/:id`. **All `alias` and `path` values must share the same params**.
### name
- **Type**: `boolean | Record<string, any> | (to: RouteLocationNormalized) => Record<string, any>` (Optional)
- **Details**:
- Allows passing down params as props to the component rendered by `router-view`. When passed to a _multiple views record_, it should be an object with the same keys as `components` or a `boolean` to be applied to each component.
- target location.
+ Allows passing down params as props to the component rendered by `router-view`. When passed to a _multiple views record_, it should be an object with the same keys as `components` or a `boolean` to be applied to each component.target location.
- **See Also**: [Passing props to Route Components](../guide/essentials/passing-props.md)
### sensitive
+
- **Type**: `boolean` (Optional)
- **Details**:
Makes the route matching case sensitive, defaults to `false`. Note this can also be set at a route level.
### strict
+
- **Type**: `boolean` (Optional)
- **Details**:
```js
await router.push('/my-profile')
if (router.currentRoute.value.redirectedFrom) {
- // redirectedFrom is resolved route location like to and from in navigation
- // guards
+ // redirectedFrom is resolved route location like to and from in navigation guards
}
```
// because it has not been created yet when this guard is called!
},
beforeRouteUpdate(to, from) {
- // called when the route that renders this component has changed,
- // but this component is reused in the new route.
- // For example, given a route with params `/users/:id`, when we
- // navigate between `/users/1` and `/users/2`, the same `UserDetails` component instance
- // will be reused, and this hook will be called when that happens.
+ // called when the route that renders this component has changed, but this component is reused in the new route.
+ // For example, given a route with params `/users/:id`, when we navigate between `/users/1` and `/users/2`,
+ // the same `UserDetails` component instance will be reused, and this hook will be called when that happens.
// Because the component is mounted while this happens, the navigation guard has access to `this` component instance.
},
beforeRouteLeave(to, from) {
- // called when the route that renders this component is about to
- // be navigated away from.
+ // called when the route that renders this component is about to be navigated away from.
// As with `beforeRouteUpdate`, it has access to `this` component instance.
},
}
### 示例:将激活的 class 应用在外层元素
-有的时候我们可能想把激活的 class 应用到一个外部元素而不是 `<a>` 标签本身,这时你可以在一个 `router-link` 中包裹该元素并使用 `v-slot` 属性来创建链接:
+有时我们可能想把激活的 class 应用到一个外部元素而不是 `<a>` 标签本身,这时你可以在一个 `router-link` 中包裹该元素并使用 `v-slot` 属性来创建链接:
```html
<router-link
`<router-view>` 暴露了一个 `v-slot` API,主要使用 `<transition>` 和 `<keep-alive>` 组件来包裹你的路由组件。
```html
-<Suspense>
- <template #default>
- <router-view v-slot="{ Component, route }">
- <transition :name="route.meta.transition || 'fade'" mode="out-in">
- <keep-alive>
+<router-view v-slot="{ Component, route }">
+ <transition :name="route.meta.transition || 'fade'" mode="out-in">
+ <keep-alive>
+ <suspense>
+ <template #default>
<component
:is="Component"
:key="route.meta.usePathKey ? route.path : undefined"
/>
- </keep-alive>
- </transition>
- </router-view>
- </template>
- <template #fallback> Loading... </template>
-</Suspense>
+ </template>
+ <template #fallback> Loading... </template>
+ </suspense>
+ </keep-alive>
+ </transition>
+</router-view>
```
- `Component`: 要传递给 `<component>` 的 VNodes `是` prop。
| 参数 | 类型 | 描述 |
| ------- | --------------------------------------------------------------------------------- | ------------------------- |
-| handler | `(error: any, to: RouteLocationNormalized, from: RouteLocationNormalized) => any` | error handler to register |
+| handler | `(error: any, to: RouteLocationNormalized, from: RouteLocationNormalized) => any` | 注册的错误处理程序 |
### push
- **类型**:`string | string[]` (可选)
- **详细内容**:
- 路由的别名。允许定义类似记录副本的额外路由。这使得路由可以简写为像这种 `/users/:id` 和
- `/u/:id`。 **所有的 `alias` 和 `path` 值必须共享相同的参数**。
+ 路由的别名。允许定义类似记录副本的额外路由。这使得路由可以简写为像这种 `/users/:id` 和 `/u/:id`。 **所有的 `alias` 和 `path` 值必须共享相同的参数**。
### name
- **类型**:`boolean | Record<string, any> | (to: RouteLocationNormalized) => Record<string, any>` (可选)
- **详细内容**:
- 允许将参数作为 props 传递给由 `router-view` 渲染的组件。当传递给一个*多视图记录*时,它应该是一个与`组件`具有相同键的对象,或者是一个应用于每个组件的`布尔值`。
+ 允许将参数作为 props 传递给由 `router-view` 渲染的组件。当传递给一个**多视图记录**时,它应该是一个与`组件`具有相同键的对象,或者是一个应用于每个组件的`布尔值`。
- **更多的内容请看**:[给路由组件传 props](../guide/essentials/passing-props.md)
+### sensitive
+
+- **类型**: `boolean` (可选)
+- **详细内容**:
+
+ 使路由匹配区分大小写,默认为`false`。注意这也可以在路由级别上设置。
+
+### strict
+
+- **类型**: `boolean` (可选)
+- **详细内容**:
+
+ 严格检查路径末尾是否有尾部斜线(`/`)。默认为 `false`,意味着默认情况下,路由 `/users` 同时匹配 `/users` 和 `/users/`。注意这也可以在路由级别上设置。
+
### meta
- **类型**:[`RouteMeta`](#routemeta) (可选)
- **类型**:标准化[路由记录](#routerecordnormalized)数组
- **详细内容**:
- 当前路由的子路由记录。如果没有则为空数组。
+ 路由被添加时的子路由记录。如果没有则为空数组。注意这个数组在 `addRoute()` 和 `removeRoute()` 被调用时不会更新。
### components
# Vue Router 和 组合式 API
+<VueSchoolLink
+ href="https://vueschool.io/lessons/router-and-the-composition-api"
+ title="Learn how to use Vue Router with the composition API"
+/>
+
引入 `setup` 和 Vue 的[组合式 API](https://v3.vuejs.org/guide/composition-api-introduction.html),开辟了新的可能性,但要想充分发挥 Vue Router 的潜力,我们需要使用一些新的函数来代替访问 `this` 和组件内导航守卫。
## 在 `setup` 中访问路由和当前路由
}
```
-`route` 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该**避免监听整个 `route`** 对象:
+`route` 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该**避免监听整个 `route`** 对象。在大多数情况下,你应该直接监听你期望改变的参数。
```js
import { useRoute } from 'vue-router'
+import { ref, watch } from 'vue'
export default {
setup() {
// 当参数更改时获取用户信息
watch(
- () => route.params,
- async newParams => {
- userData.value = await fetchUser(newParams.id)
+ () => route.params.id,
+ async newId => {
+ userData.value = await fetchUser(newId)
}
)
},
```js
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
+import { ref } from 'vue'
export default {
setup() {
```js
import { RouterLink, useLink } from 'vue-router'
+import { computed } from 'vue'
export default {
name: 'AppLink',
this.error = this.post = null
this.loading = true
// replace `getPost` with your data fetching util / API wrapper
- // 用你的数据获取 util 或 API 替换 `getPost`
getPost(this.$route.params.id, (err, post) => {
this.loading = false
if (err) {
# 动态路由
+<VueSchoolLink
+ href="https://vueschool.io/lessons/vue-router-4-dynamic-routing"
+ title="Learn how to add routes at runtime"
+/>
+
对路由的添加通常是通过 [`routes` 选项](../../api/#routes)来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由。具有可扩展接口(如 [Vue CLI UI](https://cli.vuejs.org/dev-guide/ui-api.html) )这样的应用程序可以使用它来扩展应用程序。
## 添加路由
# 扩展 RouterLink
+<VueSchoolLink
+ href="https://vueschool.io/lessons/extending-router-link-for-external-urls"
+ title="Learn how to extend router-link"
+/>
+
RouterLink 组件提供了足够的 `props` 来满足大多数基本应用程序的需求,但它并未尝试涵盖所有可能的用例,在某些高级情况下,你可能会发现自己使用了 `v-slot`。在大多数中型到大型应用程序中,值得创建一个(如果不是多个)自定义 RouterLink 组件,以在整个应用程序中重用它们。例如导航菜单中的链接,处理外部链接,添加 `inactive-class` 等。
让我们扩展 RouterLink 来处理外部链接,并在 `AppLink.vue` 文件中添加一个自定义的 `inactive-class`:
export default {
name: 'AppLink',
+ inheritAttrs: false,
props: {
// 如果使用 TypeScript,请添加 @ts-ignore
},
setup(props) {
- // toRef 允许我们提取一个 prop 并保持它的响应
- // https://v3.vuejs.org/api/refs-api.html#toref
- const { navigate, href, route, isActive, isExactActive } = useLink(
- toRef(props, 'to')
- )
+ // `props` 包含 `to` 和任何其他可以传递给 <router-link> 的 prop
+ const { navigate, href, route, isActive, isExactActive } = useLink(props)
// profit!
</AppLink>
</template>
```
-
# 路由懒加载
+<VueSchoolLink
+ href="https://vueschool.io/lessons/lazy-loading-routes-vue-cli-only"
+ title="Learn about lazy loading routes"
+/>
+
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。
Vue Router 支持开箱即用的[动态导入](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports),这意味着你可以用动态导入代替静态导入:
## 把组件按组分块
+### 使用 webpack
+
有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用[命名 chunk](https://webpack.js.org/guides/code-splitting/#dynamic-imports),一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4):
```js
```
webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。
+
+### 使用 Vite
+
+在Vite中,你可以在[`rollupOptions`](https://vitejs.dev/config/#build-rollupoptions)下定义分块:
+
+```js
+// vite.config.js
+export default defineConfig({
+ build: {
+ rollupOptions: {
+ // https://rollupjs.org/guide/en/#outputmanualchunks
+ output: {
+ manualChunks: {
+ 'group-user': [
+ './src/UserDetails',
+ './src/UserDashboard',
+ './src/UserProfileEdit',
+ ],
+ },
+ },
+ },
+})
+```
# 路由元信息
+<VueSchoolLink
+ href="https://vueschool.io/lessons/route-meta-fields"
+ title="Learn how to use route meta fields"
+/>
+
有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的`meta`属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置 `meta` 字段:
```js
# 等待导航结果
+<VueSchoolLink
+ href="https://vueschool.io/lessons/vue-router-4-detecting-navigation-failures"
+ title="Learn how to detect navigation failures"
+/>
+
当使用 `router-link` 组件时,Vue Router 会自动调用 `router.push` 来触发一次导航。虽然大多数链接的预期行为是将用户导航到一个新页面,但也有少数情况下用户将留在同一页面上:
- 用户已经位于他们正在尝试导航到的页面
# 导航守卫
+<VueSchoolLink
+ href="https://vueschool.io/lessons/route-guards"
+ title="Learn how to add navigation guards"
+/>
+
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
## 全局前置守卫
- `false`: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 `from` 路由对应的地址。
- 一个[路由地址](../../api/#routelocationraw): 通过一个路由地址跳转到一个不同的地址,就像你调用 [`router.push()`](../../api/#push) 一样,你可以设置诸如 `replace: true` 或 `name: 'home'` 之类的配置。当前的导航被中断,然后进行一个新的导航,就和 `from` 一样。
+ ```js
+ router.beforeEach(async (to, from) => {
+ if (
+ // 检查用户是否已登录
+ !isAuthenticated &&
+ // ❗️ 避免无限重定向
+ to.name !== 'Login'
+ ) {
+ // 将用户重定向到登录页面
+ return { name: 'Login' }
+ }
+ })
+
如果遇到了意料之外的情况,可能会抛出一个 `Error`。这会取消导航并且调用 [`router.onError()`](../../api/#onerror) 注册过的回调。
如果什么都没有,`undefined` 或返回 `true`,**则导航是有效的**,并调用下一个导航守卫
```js
router.beforeEach(async (to, from) => {
// canUserAccess() 返回 `true` 或 `false`
- return await canUserAccess(to)
+ const canAccess = await canUserAccess(to)
+ if (!canAccess) return '/login'
})
```
# 滚动行为
+<VueSchoolLink
+ href="https://vueschool.io/lessons/scroll-behavior"
+ title="Learn how to customize scroll behavior"
+/>
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。
# 过渡动效
+<VueSchoolLink
+ href="https://vueschool.io/lessons/route-transitions"
+ title="Learn about route transitions"
+/>
+
想要在你的路径组件上使用转场,并对导航进行动画处理,你需要使用 [v-slot API](../../api/#router-view-s-v-slot):
```html
</router-view>
```
-[Transition 的所有功能](https://v3.vuejs.org/guide/transitions-enterleave.html) 在这里同样适用。
+[Transition 的 API](https://v3.vuejs.org/guide/transitions-enterleave.html) 在这里同样适用。
## 单个路由的过渡
})
```
+## 强制在复用的视图之间进行过渡
+
+Vue 可能会自动复用看起来相似的组件,从而忽略了任何过渡。幸运的是,可以[添加一个 `key` 属性](https://v3.vuejs.org/api/special-attributes.html#key)来强制过渡。这也允许你在相同路由上使用不同的参数触发过渡:
+
+```vue
+<router-view v-slot="{ Component, route }">
+ <transition name="fade">
+ <component :is="Component" :key="route.path" />
+ </transition>
+</router-view>
+```
+
<!-- TODO: interactive example -->
<!-- See full example [here](https://github.com/vuejs/vue-router/blob/dev/examples/transitions/app.js). -->
# 带参数的动态路由匹配
+<VueSchoolLink
+ href="https://vueschool.io/lessons/dynamic-routes"
+ title="Learn about dynamic route matching with params"
+/>
+
很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 `User` 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 _路径参数_ :
```js
## 响应路由参数的变化
+<VueSchoolLink
+ href="https://vueschool.io/lessons/reacting-to-param-changes"
+ title="Learn how to react to param changes"
+/>
+
使用带有参数的路由时需要注意的是,当用户从 `/users/johnny` 导航到 `/users/jolyne` 时,**相同的组件实例将被重复使用**。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。**不过,这也意味着组件的生命周期钩子不会被调用**。
要对同一个组件中参数的变化做出响应的话,你可以简单地 watch `$route` 对象上的任意属性,在这个场景中,就是 `$route.params` :
## 捕获所有路由或 404 Not found 路由
+<VueSchoolLink
+ href="https://vueschool.io/lessons/404-not-found-page"
+ title="Learn how to make a catch all/404 not found route"
+/>
+
常规参数只匹配 url 片段之间的字符,用 `/` 分隔。如果我们想匹配**任意路径**,我们可以使用自定义的 _路径参数_ 正则表达式,在 _路径参数_ 后面的括号中加入 正则表达式 :
```js
```js
this.$router.push({
name: 'NotFound',
- params: { pathMatch: this.$route.path.split('/') },
+ // 保留当前路径并删除第一个字符,以避免目标 URL 以 `//` 开头。
+ params: { pathMatch: this.$route.path.substring(1).split('/') },
+ // 保留现有的查询和 hash 值,如果有的话
+ query: this.$route.query,
+ hash: this.$route.hash,
})
```
# 不同的历史模式
+<VueSchoolLink
+ href="https://vueschool.io/lessons/history-mode"
+ title="Learn about the differences between Hash Mode and HTML5 Mode"
+/>
+
在创建路由器实例时,`history` 配置允许我们在不同的历史模式中进行选择。
## Hash 模式
# 命名路由
+<VueSchoolLink
+ href="https://vueschool.io/lessons/named-routes"
+ title="Learn about the named routes"
+/>
+
除了 `path` 之外,你还可以为任何路由提供 `name`。这有以下优点:
- 没有硬编码的 URL
# 命名视图
+<VueSchoolLink
+ href="https://vueschool.io/lessons/vue-router-4-named-views"
+ title="Learn how to use named views"
+/>
+
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 `sidebar` (侧导航) 和 `main` (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 `router-view` 没有设置名字,那么默认为 `default`。
```html
# 编程式导航
+<VueSchoolLink
+ href="https://vueschool.io/lessons/vue-router-4-programmatic-navigation"
+ title="Learn how to navigate programmatically"
+/>
+
除了使用 `<router-link>` 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
## 导航到不同的位置
router.push({ path: '/user', params: { username } }) // -> /user
```
+当指定 `params` 时,可提供 `string` 或 `number` 参数(或者对于[可重复的参数](./route-matching-syntax.md#repeatable-params)可提供一个数组)。**任何其他类型(如 `undefined`、`false` 等)都将被自动字符串化**。对于[可选参数](./route-matching-syntax.md#repeatable-params),你可以提供一个空字符串(`""`)来跳过它。
+
由于属性 `to` 与 `router.push` 接受的对象种类相同,所以两者的规则完全相同。
`router.push` 和所有其他导航方法都会返回一个 _Promise_,让我们可以等到导航完成后才知道是成功还是失败。我们将在 [Navigation Handling](../advanced/navigation-failures.md) 中详细介绍。
## 横跨历史
+<VueSchoolLink
+ href="https://vueschool.io/lessons/go-back"
+ title="Learn how to use Vue Router to go back"
+/>
+
该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 `window.history.go(n)`。
例子
// 向前移动一条记录,与 router.forward() 相同
router.go(1)
-// 返回一条记录,与router.back() 相同
+// 返回一条记录,与 router.back() 相同
router.go(-1)
// 前进 3 条记录
因此,如果你已经熟悉 [Browser History APIs](https://developer.mozilla.org/en-US/docs/Web/API/History_API),在使用 Vue Router 时,操作历史记录就会觉得很熟悉。
-值得一提的是,无论在创建路由器实例时传递什么样的[`history` 配置](../../api/#history),Vue Router 的导航方法(`push`、`replace`、`go`)都能始终如一地工作。
+值得一提的是,无论在创建路由器实例时传递什么样的 [`history` 配置](../../api/#history),Vue Router 的导航方法( `push`、`replace`、`go` )都能始终正常工作。
# 嵌套路由
+<VueSchoolLink
+ href="https://vueschool.io/lessons/nested-routes"
+ title="Learn about nested routes"
+/>
+
一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的片段通常对应于特定的嵌套组件结构,例如:
```
# 将 props 传递给路由组件
+<VueSchoolLink
+ href="https://vueschool.io/lessons/route-props"
+ title="Learn how to pass props to route components"
+/>
+
在你的组件中使用 `$route` 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 `props` 配置来解除这种行为:
我们可以将下面的代码
```js
const User = {
+ // 请确保添加一个与路由参数完全相同的 prop 名
props: ['id'],
template: '<div>User {{ id }}</div>'
}
URL `/search?q=vue` 将传递 `{query: 'vue'}` 作为 props 传给 `SearchUser` 组件。
请尽可能保持 `props` 函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 vue 才可以对状态变化做出反应。
-
-高级使用方法,请查看[示例](https://github.com/vuejs/vue-router/blob/dev/examples/route-props/app.js).
# 重定向和别名
+<VueSchoolLink
+ href="https://vueschool.io/lessons/vue-router-4-redirect-and-alias"
+ title="Learn how to use redirect and alias"
+/>
+
## 重定向
重定向也是通过 `routes` 配置来完成,下面例子是从 `/home` 重定向到 `/`:
-
```js
const routes = [{ path: '/home', redirect: '/' }]
```
```js
const routes = [
{
+ // 将总是把/users/123/posts重定向到/users/123/profile。
path: '/users/:id/posts',
redirect: to => {
- // 方法接收目标路由作为参数
- // return 重定向的字符串路径/路径对象
+ // 该函数接收目标路由作为参数
+ // 相对位置不以`/`开头
+ // 或 { path: 'profile'}
+ return 'profile'
},
},
]
# 路由的匹配语法
+<VueSchoolLink
+ href="https://vueschool.io/lessons/vue-router-4-advanced-routes-matching-syntax"
+ title="Learn how to use advanced route routes' matching syntax"
+/>
+
大多数应用都会使用 `/about` 这样的静态路由和 `/users/:userId` 这样的动态路由,就像我们刚才在[动态路由匹配](./dynamic-matching.md)中看到的那样,但是 Vue Router 可以提供更多的方式!
:::tip
]
```
+## Sensitive 与 strict 路由配置
+
+默认情况下,所有路由是不区分大小写的,并且能匹配带有或不带有尾部斜线的路由。例如,路由 `/users` 将匹配 `/users`、`/users/`、甚至 `/Users/`。这种行为可以通过 `strict` 和 `sensitive` 选项来修改,它们可以既可以应用在整个全局路由上,又可以应用于当前路由上:
+
+```js
+const router = createRouter({
+ history: createWebHistory(),
+ routes: [
+ // 将匹配 /users/posva 而非:
+ // - /users/posva/ 当 strict: true
+ // - /Users/posva 当 sensitive: true
+ { path: '/users/:id', sensitive: true },
+ // 将匹配 /users, /Users, 以及 /users/42 而非 /users/ 或 /users/42/
+ { path: '/users/:id?' },
+ ]
+ strict: true, // applies to all routes
+})
+```
+
## 可选参数
你也可以通过使用 `?` 修饰符(0 个或 1 个)将一个参数标记为可选:
# 入门
+<VueSchoolLink
+ href="https://vueschool.io/courses/vue-router-4-for-everyone"
+ title="Learn how to build powerful Single Page Applications with the Vue Router on Vue School"
+/>
+
用 Vue + Vue Router 创建单页应用非常简单:通过 Vue.js,我们已经用组件组成了我们的应用。当加入 Vue Router 时,我们需要做的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲染它们。下面是一个基本的例子:
## HTML
})
```
-### 删除了 `RouterOptions` 中的 `fallback` 属性
+### 删除了 `fallback` 属性
创建路由时不再支持 `fallback` 属性:
{
path: '/dashboard',
name: 'dashboard-parent',
- component: DashboardParent
+ component: DashboardParent,
children: [
{ path: '', name: 'dashboard', component: DashboardDefault },
- { path: 'settings', name: 'dashboard-settings', component: DashboardSettings },
+ {
+ path: 'settings',
+ name: 'dashboard-settings',
+ component: DashboardSettings,
+ },
],
},
]
```
-现在,导航或解析到命名的路由 `dashboard` 时,会产生一个**不带斜线的 URL**:
+现在,导航或解析到命名的路由 `dashboard` 时,会产生一个**不带斜线的** URL:
```js
router.resolve({ name: 'dashboard' }).href // '/dashboard'
给定任何[规范化的路由地址](../../api/#routelocationnormalized):
+- `path`, `fullPath`中的值不再被解码了。例如,直接在地址栏上写 "https://example.com/hello world",将得到编码后的版本:"https://example.com/hello%20world",而 "path "和 "fullPath "都是"/hello%20world"。
- `hash` 现在被解码了,这样就可以复制过来。`router.push({ hash: $route.hash })` 可以直接用于 [scrollBehavior](../../api/#scrollbehavior) 的 `el` 配置中。
- 当使用 `push`、`resolve` 和 `replace` 并在对象中提供 `string` 地址或 `path` 属性时,**必须进行编码**(像以前的版本一样)。另一方面,`params`、`query` 和 `hash` 必须以未编码的版本提供。
- 斜线字符(`/`)现在已在 `params` 内正确解码,同时仍在 URL 上产生一个编码版本:`%2F`。
---
home: true
+
heroImage: /logo.png
actionText: 入门 →
actionLink: /zh/introduction.html
+altActionLink: https://vueschool.io/courses/vue-router-4-for-everyone?friend=vuerouter&utm_source=vuerouter&utm_medium=link&utm_campaign=homepage
+altActionText: 免费视频课程
+
+features:
+ - title: 🛣 富有表现力的路由语法
+ details: 用直观且强大的语法来定义静态或动态路由。
+ - title: 🛑 细致的导航控制
+ details: 可拦截任何导航并更精确地控制其结果。
+ - title: 🧱 基于组件的配置方法
+ details: 将每条路由映射到应该显示的组件上。
+ - title: 🔌 支持历史模式
+ details: 有 HTML5、hash 或记忆历史模式可供选择。
+ - title: 🎚 支持滚动控制
+ details: 可精确控制每个页面的滚动位置。
+ - title: 🌐 支持自动编码
+ details: 可直接在代码中使用 unicode 字符(你好)。
footer: MIT Licensed | Copyright © 2014-present Evan You, Eduardo San Martin Morote
---
npm install vue-router@4
```
-## 开发版本构建
-
-如果你想使用最新的开发版本,你需要直接从 GitHub 上克隆并自己构建 `vue-router`。
+## yarn
```bash
-git clone https://github.com/vuejs/vue-router.git node_modules/vue-router
-cd node_modules/vue-router
-npm install
-npm run build
-```
+yarn add vue-router@4
+```
\ No newline at end of file
# 介绍
+<VueSchoolLink
+ href="https://vueschool.io/courses/vue-router-4-for-everyone"
+ title="Learn how to build powerful Single Page Applications with the Vue Router on Vue School"
+/>
+
Vue Router 是 [Vue.js](http://v3.vuejs.org) 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:
- 嵌套路由映射