From: Jinjiang Date: Tue, 11 Jun 2024 03:20:40 +0000 (+0800) Subject: docs(zh): sync to d842b6f (#2244) X-Git-Tag: v4.4.0~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=50ac702e3a542b8c55659f574e48a60d042a61ec;p=thirdparty%2Fvuejs%2Frouter.git docs(zh): sync to d842b6f (#2244) * docs(zh): sync to d842b6f * docs(zh): translate the new docs * docs(zh): update the checkpoint * Update packages/docs/zh/guide/essentials/named-routes.md Co-authored-by: GU Yiling * Apply suggestions from code review Co-authored-by: GU Yiling * Update zh.ts * Update data-fetching.md * Update composition-api.md * Update navigation-guards.md * Update navigation-guards.md --------- Co-authored-by: GU Yiling --- diff --git a/packages/docs/.vitepress/config/zh.ts b/packages/docs/.vitepress/config/zh.ts index 7613a8b1..dbc6ba4a 100644 --- a/packages/docs/.vitepress/config/zh.ts +++ b/packages/docs/.vitepress/config/zh.ts @@ -57,15 +57,9 @@ export const zhConfig: LocaleSpecificConfig = { ], sidebar: { - '/zh/api/': [ - { - text: 'packages', - items: [{ text: 'vue-router', link: '/zh/api/' }], - }, - ], - '/zh/': [ { + text: '设置', items: [ { text: '介绍', @@ -96,14 +90,14 @@ export const zhConfig: LocaleSpecificConfig = { text: '嵌套路由', link: '/zh/guide/essentials/nested-routes.html', }, - { - text: '编程式导航', - link: '/zh/guide/essentials/navigation.html', - }, { text: '命名路由', link: '/zh/guide/essentials/named-routes.html', }, + { + text: '编程式导航', + link: '/zh/guide/essentials/navigation.html', + }, { text: '命名视图', link: '/zh/guide/essentials/named-views.html', @@ -116,6 +110,10 @@ export const zhConfig: LocaleSpecificConfig = { text: '路由组件传参', link: '/zh/guide/essentials/passing-props.html', }, + { + text: '匹配当前路由的链接', + link: '/zh/guide/essentials/active-links.html', + }, { text: '不同的历史记录模式', link: '/zh/guide/essentials/history-mode.html', @@ -188,6 +186,13 @@ export const zhConfig: LocaleSpecificConfig = { ], }, ], + + '/zh/api/': [ + { + text: 'packages', + items: [{ text: 'vue-router', link: '/zh/api/' }], + }, + ], }, }, } diff --git a/packages/docs/.vitepress/translation-status.json b/packages/docs/.vitepress/translation-status.json index ea46a912..85dfe912 100644 --- a/packages/docs/.vitepress/translation-status.json +++ b/packages/docs/.vitepress/translation-status.json @@ -1,6 +1,6 @@ { "zh": { - "hash": "35a9c1b", - "date": "2023-12-16" + "hash": "d842b6f", + "date": "2024-05-17" } } \ No newline at end of file diff --git a/packages/docs/zh/guide/advanced/composition-api.md b/packages/docs/zh/guide/advanced/composition-api.md index da2e9b82..2385633e 100644 --- a/packages/docs/zh/guide/advanced/composition-api.md +++ b/packages/docs/zh/guide/advanced/composition-api.md @@ -5,87 +5,81 @@ title="Learn how to use Vue Router with the composition API" /> -引入 `setup` 和 Vue 的[组合式 API](https://cn.vuejs.org/guide/extras/composition-api-faq.html),开辟了新的可能性,但要想充分发挥 Vue Router 的潜力,我们需要使用一些新的函数来代替访问 `this` 和组件内导航守卫。 +Vue 的[组合式 API](https://cn.vuejs.org/guide/extras/composition-api-faq.html) 的引入开辟了新的可能性,但要想充分发挥 Vue Router 的潜力,我们需要使用一些新的函数来代替访问 `this` 和组件内导航守卫。 ## 在 `setup` 中访问路由和当前路由 -因为我们在 `setup` 里面没有访问 `this`,所以我们不能再直接访问 `this.$router` 或 `this.$route`。作为替代,我们使用 `useRouter` 和 `useRoute` 函数: +因为我们在 `setup` 里面没有访问 `this`,所以我们不能直接访问 `this.$router` 或 `this.$route`。作为替代,我们使用 `useRouter` 和 `useRoute` 函数: -```js +```vue + ``` -`route` 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该**避免监听整个 `route`** 对象。在大多数情况下,你应该直接监听你期望改变的参数。 +`route` 对象是一个响应式对象。在多数情况下,你应该**避免监听整个 `route`** 对象,同时直接监听你期望改变的参数。 -```js +```vue + ``` -请注意,在模板中我们仍然可以访问 `$router` 和 `$route`,所以不需要在 `setup` 中返回 `router` 或 `route`。 +请注意,在模板中我们仍然可以访问 `$router` 和 `$route`,所以如果你只在模板中使用这些对象的话,是不需要 `useRouter` 或 `useRoute` 的。 ## 导航守卫 -虽然你仍然可以通过 `setup` 函数来使用组件内的导航守卫,但 Vue Router 将更新和离开守卫作为 组合式 API 函数公开: +Vue Router 将更新和离开守卫作为组合式 API 函数公开: -```js +```vue + ``` 组合式 API 守卫也可以用在任何由 `` 渲染的组件中,它们不必像组件内守卫那样直接用在路由组件上。 @@ -94,40 +88,34 @@ export default { Vue Router 将 RouterLink 的内部行为作为一个组合式函数 (composable) 公开。它接收一个类似 `RouterLink` 所有 prop 的响应式对象,并暴露底层属性来构建你自己的 `RouterLink` 组件或生成自定义链接: -```js +```vue + ``` 注意在 RouterLink 的 `v-slot` 中可以访问与 `useLink` 组合式函数相同的属性。 diff --git a/packages/docs/zh/guide/advanced/data-fetching.md b/packages/docs/zh/guide/advanced/data-fetching.md index 521a6396..4355a30d 100644 --- a/packages/docs/zh/guide/advanced/data-fetching.md +++ b/packages/docs/zh/guide/advanced/data-fetching.md @@ -10,11 +10,13 @@ ## 导航完成后获取数据 -当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。 +当你使用这种方式时,我们会马上导航和渲染组件,然后在组件中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。 -假设我们有一个 `Post` 组件,需要基于 `$route.params.id` 获取文章数据: +假设我们有一个 `Post` 组件,需要基于 `route.params.id` 获取文章数据: -```html +::: code-group + +```vue [Composition API] + + ``` -```js +```vue [Options API] + + + ``` +::: + ## 在导航完成前获取数据 通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 `beforeRouteEnter` 守卫中获取数据,当数据获取成功后只调用 `next` 方法: @@ -81,28 +129,27 @@ export default { } }, beforeRouteEnter(to, from, next) { - getPost(to.params.id, (err, post) => { - // `setData` 方法定义在下面的代码中 - next(vm => vm.setData(err, post)) - }) + try { + const post = await getPost(to.params.id) + // `setPost` 方法定义在下面的代码中 + next(vm => vm.setPost(post)) + } catch (err) { + // `setError` 方法定义在下面的代码中 + next(vm => vm.setError(err)) + } }, // 路由改变前,组件就已经渲染完了 // 逻辑稍稍不同 async beforeRouteUpdate(to, from) { this.post = null - try { - this.post = await getPost(to.params.id) - } catch (error) { - this.error = error.toString() - } + getPost(to.params.id).then(this.setPost).catch(this.setError) }, methods: { - setData(error, post) { - if (error) { - this.error = error - } else { - this.post = post - } + setPost(post) { + this.post = post + }, + setError(err) { + this.error = err.toString() } } } diff --git a/packages/docs/zh/guide/advanced/dynamic-routing.md b/packages/docs/zh/guide/advanced/dynamic-routing.md index 380b7f22..ba7b602d 100644 --- a/packages/docs/zh/guide/advanced/dynamic-routing.md +++ b/packages/docs/zh/guide/advanced/dynamic-routing.md @@ -30,7 +30,7 @@ router.addRoute({ path: '/about', component: About }) ```js router.addRoute({ path: '/about', component: About }) -// 我们也可以使用 this.$route 或 route = useRoute() (在 setup 中) +// 我们也可以使用 this.$route 或 useRoute() router.replace(router.currentRoute.value.fullPath) ``` diff --git a/packages/docs/zh/guide/advanced/extending-router-link.md b/packages/docs/zh/guide/advanced/extending-router-link.md index 57230244..16a21996 100644 --- a/packages/docs/zh/guide/advanced/extending-router-link.md +++ b/packages/docs/zh/guide/advanced/extending-router-link.md @@ -9,7 +9,28 @@ RouterLink 组件提供了足够的 `props` 来满足大多数基本应用程序 让我们扩展 RouterLink 来处理外部链接,并在 `AppLink.vue` 文件中添加一个自定义的 `inactive-class`: -```vue +::: code-group + +```vue [Composition API] + + +``` +```vue [Options API] + + ``` +::: + 如果你喜欢使用渲染函数或创建 `computed` 属性,你可以使用 [Composition API](./composition-api.md) 中的 `useLink` : ```js diff --git a/packages/docs/zh/guide/advanced/meta.md b/packages/docs/zh/guide/advanced/meta.md index 939d5df0..1063e01f 100644 --- a/packages/docs/zh/guide/advanced/meta.md +++ b/packages/docs/zh/guide/advanced/meta.md @@ -38,7 +38,7 @@ const routes = [ 例如,根据上面的路由配置,`/posts/new` 这个 URL 将会匹配父路由记录 (`path: '/posts'`) 以及子路由记录 (`path: 'new'`)。 -一个路由匹配到的所有路由记录会暴露为 `$route` 对象(还有在导航守卫中的路由对象)的`$route.matched` 数组。我们需要遍历这个数组来检查路由记录中的 `meta` 字段,但是 Vue Router 还为你提供了一个 `$route.meta` 方法,它是一个非递归合并**所有 `meta`** 字段(从父字段到子字段)的方法。这意味着你可以简单地写 +一个路由匹配到的所有路由记录会暴露为 `route` 对象(还有在导航守卫中的路由对象)的`route.matched` 数组。我们需要遍历这个数组来检查路由记录中的 `meta` 字段,但是 Vue Router 还为你提供了一个 `route.meta` 方法,它是一个非递归合并**所有 `meta`** 字段(从父字段到子字段)的方法。这意味着你可以简单地写 ```js router.beforeEach((to, from) => { diff --git a/packages/docs/zh/guide/advanced/navigation-failures.md b/packages/docs/zh/guide/advanced/navigation-failures.md index fccc5594..79460435 100644 --- a/packages/docs/zh/guide/advanced/navigation-failures.md +++ b/packages/docs/zh/guide/advanced/navigation-failures.md @@ -62,8 +62,6 @@ if (isNavigationFailure(failure, NavigationFailureType.aborted)) { 如果你忽略第二个参数: `isNavigationFailure(failure)`,那么就只会检查这个 `failure` 是不是一个 _Navigation Failure_。 ::: - - ## 全局导航故障 你可以用 [`router.afterEach()` 导航守卫](./navigation-guards.md#Global-After-Hooks)检测全局导航故障: diff --git a/packages/docs/zh/guide/advanced/navigation-guards.md b/packages/docs/zh/guide/advanced/navigation-guards.md index 7952384c..e84e6037 100644 --- a/packages/docs/zh/guide/advanced/navigation-guards.md +++ b/packages/docs/zh/guide/advanced/navigation-guards.md @@ -86,7 +86,7 @@ router.beforeEach((to, from, next) => { ## 全局解析守卫 -你可以用 `router.beforeResolve` 注册一个全局守卫。这和 `router.beforeEach` 类似,因为它在**每次导航**时都会触发,不同的是,解析守卫刚好会在导航被确认之前、**所有组件内守卫和异步路由组件被解析之后**调用。这里有一个例子,确保用户可以访问[自定义 meta](./meta.md) 属性 `requiresCamera` 的路由: +你可以用 `router.beforeResolve` 注册一个全局守卫。这和 `router.beforeEach` 类似,因为它在**每次导航**时都会触发,不同的是,解析守卫刚好会在导航被确认之前、**所有组件内守卫和异步路由组件被解析之后**调用。这里有一个例子,根据路由在[元信息](./meta.md)中的 `requiresCamera` 属性确保用户访问摄像头的权限: ```js router.beforeResolve(async to => { @@ -198,7 +198,28 @@ const routes = [ ] ``` -请注意,你也可以通过使用[路径 meta 字段](./meta.md)和全局导航守卫来实现类似的行为。 +当配合[嵌套路由](../essentials/nested-routes)使用时,父路由和子路由都可以使用 `beforeEnter`。如果放在父级路由上,路由在具有相同父级的子路由之间移动时,它不会被触发。例如: + +```js +const routes = [ + { + path: '/user', + beforeEnter() { + // ... + }, + children: [ + { path: 'list', component: UserList }, + { path: 'details', component: UserDetails }, + ], + }, +] +``` + +示例中的 `beforeEnter` 在 `/user/list` 和 `/user/details` 之间移动时不会被调用,因为它们共享相同的父级路由。如果我们直接将 `beforeEnter` 守卫放在 `details` 路由上,那么在这两个路由之间移动时就会被调用。 + +::: tip +你也可以通过使用[路由元信息字段](./meta.md)和全局导航守卫来实现类似的行为。 +::: ## 组件内的守卫 @@ -212,9 +233,9 @@ const routes = [ - `beforeRouteUpdate` - `beforeRouteLeave` -```js -const UserDetails = { - template: `...`, +```vue + ``` `beforeRouteEnter` 守卫 **不能** 访问 `this`,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。 @@ -265,7 +287,7 @@ beforeRouteLeave (to, from) { ### 使用组合 API -如果你正在使用[组合 API 和 `setup` 函数](https://cn.vuejs.org/api/composition-api-setup.html)来编写组件,你可以通过 `onBeforeRouteUpdate` 和 `onBeforeRouteLeave` 分别添加 update 和 leave 守卫。 请参考[组合 API 部分](./composition-api.md#导航守卫)以获得更多细节。 +如果你正在使用组合式 API 编写组件,你可以通过 `onBeforeRouteUpdate` 和 `onBeforeRouteLeave` 分别添加 update 和 leave 守卫。 请参考[组合式 API 部分](./composition-api.md#导航守卫)以获得更多细节。 ## 完整的导航解析流程 diff --git a/packages/docs/zh/guide/essentials/active-links.md b/packages/docs/zh/guide/essentials/active-links.md new file mode 100644 index 00000000..76f93a43 --- /dev/null +++ b/packages/docs/zh/guide/essentials/active-links.md @@ -0,0 +1,80 @@ + + +# Active links + +It's common for applications to have a navigation component that renders a list of RouterLink components. Within that list, we might want to style links to the currently active route differently from the others. + +The RouterLink component adds two CSS classes to active links, `router-link-active` and `router-link-exact-active`. To understand the difference between them, we first need to consider how Vue Router decides that a link is _active_. + +## When are links active? + +A RouterLink is considered to be ***active*** if: + +1. It matches the same route record (i.e. configured route) as the current location. +2. It has the same values for the `params` as the current location. + +If you're using [nested routes](./nested-routes), any links to ancestor routes will also be considered active if the relevant `params` match. + +Other route properties, such as the [`query`](../../api/interfaces/RouteLocationNormalized#query), are not taken into account. + +The path doesn't necessarily need to be a perfect match. For example, using an [`alias`](./redirect-and-alias#Alias) would still be considered a match, so long as it resolves to the same route record and `params`. + +If a route has a [`redirect`](./redirect-and-alias#Redirect), it won't be followed when checking whether a link is active. + +## Exact active links + +An ***exact*** match does not include ancestor routes. + +Let's imagine we have the following routes: + +```js +const routes = [ + { + path: '/user/:username', + component: User, + children: [ + { + path: 'role/:roleId', + component: Role, + } + ] + } +] +``` + +Then consider these two links: + +```vue-html + + User + + + Role + +``` + +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`. + +## 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: + +```vue-html + +``` + +The default class names can also be changed globally by passing the `linkActiveClass` and `linkExactActiveClass` options to `createRouter()`: + +```js +const router = createRouter({ + linkActiveClass: 'border-indigo-500', + linkExactActiveClass: 'border-indigo-700', + // ... +}) +``` + +See [Extending RouterLink](../advanced/extending-router-link) for more advanced customization techniques using the `v-slot` API. diff --git a/packages/docs/zh/guide/essentials/dynamic-matching.md b/packages/docs/zh/guide/essentials/dynamic-matching.md index 7d0646f1..5ba892e8 100644 --- a/packages/docs/zh/guide/essentials/dynamic-matching.md +++ b/packages/docs/zh/guide/essentials/dynamic-matching.md @@ -8,9 +8,7 @@ 很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 `User` 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 _路径参数_ : ```js -const User = { - template: '
User
', -} +import User from './User.vue' // 这些都会传递给 `createRouter` const routes = [ @@ -21,22 +19,25 @@ const routes = [ 现在像 `/users/johnny` 和 `/users/jolyne` 这样的 URL 都会映射到同一个路由。 -_路径参数_ 用冒号 `:` 表示。当一个路由被匹配时,它的 _params_ 的值将在每个组件中以 `this.$route.params` 的形式暴露出来。因此,我们可以通过更新 `User` 的模板来呈现当前的用户 ID: +_路径参数_ 用冒号 `:` 表示。当一个路由被匹配时,它的 _params_ 的值将在每个组件中以 `route.params` 的形式暴露出来。因此,我们可以通过更新 `User` 的模板来呈现当前的用户 ID: -```js -const User = { - template: '
User {{ $route.params.id }}
', -} +```vue + ``` 你可以在同一个路由中设置有多个 _路径参数_,它们会映射到 `$route.params` 上的相应字段。例如: -| 匹配模式 | 匹配路径 | \$route.params | +| 匹配模式 | 匹配路径 | route.params | | ------------------------------ | ------------------------ | ---------------------------------------- | | /users/:username | /users/eduardo | `{ username: 'eduardo' }` | | /users/:username/posts/:postId | /users/eduardo/posts/123 | `{ username: 'eduardo', postId: '123' }` | -除了 `$route.params` 之外,`$route` 对象还公开了其他有用的信息,如 `$route.query`(如果 URL 中存在参数)、`$route.hash` 等。你可以在 [API 参考](../../api/#routelocationnormalized)中查看完整的细节。 +除了 `route.params` 之外,`route` 对象还公开了其他有用的信息,如 `route.query`(如果 URL 中存在参数)、`route.hash` 等。你可以在 [API 参考](../../api/#routelocationnormalized)中查看完整的细节。 这个例子的 demo 可以在[这里](https://codesandbox.io/s/route-params-vue-router-examples-mlb14?from-embed&initialpath=%2Fusers%2Feduardo%2Fposts%2F1)找到。 @@ -59,32 +60,68 @@ const User = { 要对同一个组件中参数的变化做出响应的话,你可以简单地 watch `$route` 对象上的任意属性,在这个场景中,就是 `$route.params` : -```js -const User = { - template: '...', +::: code-group + +```vue [Composition API] + +``` + +```vue [Options API] + ``` -或者,使用 `beforeRouteUpdate` [导航守卫](../advanced/navigation-guards.md),它也可以取消导航: +::: -```js -const User = { - template: '...', +或者,使用 `beforeRouteUpdate` [导航守卫](../advanced/navigation-guards.md),它还允许你取消导航: + +::: code-group + +```vue [Composition API] + +``` + +```vue [Options API] + ``` +::: + ## 捕获所有路由或 404 Not found 路由 -除了 `path` 之外,你还可以为任何路由提供 `name`。这有以下优点: - -- 没有硬编码的 URL -- `params` 的自动编码/解码。 -- 防止你在 url 中出现打字错误。 -- 绕过路径排序(如显示一个) +当创建一个路由时,我们可以选择给路由一个 `name`: ```js const routes = [ { path: '/user/:username', - name: 'user', - component: User, - }, + name: 'profile', // [!code highlight] + component: User + } ] ``` -要链接到一个命名的路由,可以向 `router-link` 组件的 `to` 属性传递一个对象: +然后我们可以使用 `name` 而不是 `path` 来传递 `to` 属性给 ``: -```html - - User +```vue-html + + User profile ``` -这跟代码调用 `router.push()` 是一回事: +上述示例将创建一个指向 `/user/erina` 的链接。 -```js -router.push({ name: 'user', params: { username: 'erina' } }) -``` +- [在演练场上查看](https://play.vuejs.org/#eNqtVVtP2zAU/itWNqlFauNNIB6iUMEQEps0NjH2tOzBtKY1JLZlO6VTlP++4+PcelnFwyRofe7fubaKCiZk/GyjJBKFVsaRiswNZ45faU1q8mRUQUbrko8yuaPwlRfK/LkV1sHXpGHeq9JxMzScGmT19t5xkMaUaR1vOb9VBe+kntgWXz2Cs06O1LbCTwvRW7knGnEm50paRwIYcrEFd1xlkpBVyCQ5lN74ZOJV0Nom5JcnCFRCM7dKyIiOJkSygsNzBZiBmivAI7l0SUipRvuhCfPge7uWHBiGZPctS0iLJv7T2/YutFFPIt+JjgUJPn7DZ32CtWg7PIZ/4BASg7txKE6gC1VKNx69gw6NTqJJ1HQK5iR1vNA52M+8Yrr6OLuD+AuCtbQpBQYK9Oy6NAZAhLI1KKuKvEc69jSp65Tqw/oh3V7f00P9MsdveOWiecE75DDNhXwhiVMXWVRttYbUWdRpE2xOZ0sHxq1v2jl/a5jQyZ042Mv/HKjvt2aGFTCXFWmnAsTcCMkAxw4SHIjG9E2AUtpUusWyFvyVUGCltBsFmJB2W/dHZCHWswdYLwJ/XiulnrNr323zcQeodthDuAHTgmm4aEqCH1zsrBHYLIISheyyqD9Nnp1FK+e0TSgtpX5ZxrBBtNe4PItP4w8Q07oBN+a2mD4a9erPzDN4bzY1iy5BiS742imV2ynT4l8h9hQvz+Pz+COU/pGCdyrkgm/Qt3ddw/5Cms7CLXsSy50k/dJDT8037QTcuq1kWZ6r1y/Ic6bkHdD5is9fDvCf7SZA/m44ZLfmg+QcM0vugvjmxx3fwLsTFmpRwlwdE95zq/LSYwxqn0q5ANgDPUT7GXsm5PLB3mwcl7ZNygPFaqA+NvL6SOo93NP4bFDF9sfh+LThtgxvkF80fyxxy/Ac7U9i/RcYNWrd)。 -在这两种情况下,路由将导航到路径 `/user/erina`。 +使用 `name` 有很多优点: -完整的例子在[这里](https://github.com/vuejs/vue-router/blob/dev/examples/named-routes/app.js). +- 没有硬编码的 URL。 +- `params` 的自动编码/解码。 +- 防止你在 URL 中出现打字错误。 +- 绕过路径排序,例如展示一个匹配相同路径但排序较低的路由。 所有路由的命名**都必须是唯一的**。如果为多条路由添加相同的命名,路由器只会保留最后那一条。你可以在[动态路由](../advanced/dynamic-routing.md#Removing-routes)章节了解更多。 + +Vue Router 有很多其他部分可以传入网址,例如 `router.push()` 和 `router.replace()` 方法。我们将在[编程式导航](./navigation.md)指南中详细介绍这些方法。就像 `to` 属性一样,这些方法也支持通过 `name` 传入网址: + +```js +router.push({ name: 'user', params: { username: 'erina' } }) +``` diff --git a/packages/docs/zh/guide/essentials/named-views.md b/packages/docs/zh/guide/essentials/named-views.md index 11e8f5f1..b9c568a9 100644 --- a/packages/docs/zh/guide/essentials/named-views.md +++ b/packages/docs/zh/guide/essentials/named-views.md @@ -7,10 +7,10 @@ 有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 `sidebar` (侧导航) 和 `main` (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 `router-view` 没有设置名字,那么默认为 `default`。 -```html - - - +```vue-html + + + ``` 一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 `components` 配置 (带上 **s**): diff --git a/packages/docs/zh/guide/essentials/nested-routes.md b/packages/docs/zh/guide/essentials/nested-routes.md index 56e4fd2a..7984ae5e 100644 --- a/packages/docs/zh/guide/essentials/nested-routes.md +++ b/packages/docs/zh/guide/essentials/nested-routes.md @@ -8,30 +8,38 @@ 一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的片段通常对应于特定的嵌套组件结构,例如: ``` -/user/johnny/profile /user/johnny/posts -+------------------+ +-----------------+ -| User | | User | -| +--------------+ | | +-------------+ | -| | Profile | | +------------> | | Posts | | -| | | | | | | | -| +--------------+ | | +-------------+ | -+------------------+ +-----------------+ +/user/johnny/profile /user/johnny/posts +┌──────────────────┐ ┌──────────────────┐ +│ User │ │ User │ +│ ┌──────────────┐ │ │ ┌──────────────┐ │ +│ │ Profile │ │ ●────────────▶ │ │ Posts │ │ +│ │ │ │ │ │ │ │ +│ └──────────────┘ │ │ └──────────────┘ │ +└──────────────────┘ └──────────────────┘ ``` 通过 Vue Router,你可以使用嵌套路由配置来表达这种关系。 接着上节创建的 app : -```html -
- -
+```vue + + +``` + +```vue + + ``` ```js -const User = { - template: '
User {{ $route.params.id }}
', -} +import User from './User.vue' // 这些都会传递给 `createRouter` const routes = [{ path: '/user/:id', component: User }] @@ -39,15 +47,14 @@ const routes = [{ path: '/user/:id', component: User }] 这里的 `` 是一个顶层的 `router-view`。它渲染顶层路由匹配的组件。同样地,一个被渲染的组件也可以包含自己嵌套的 ``。例如,如果我们在 `User` 组件的模板内添加一个 ``: -```js -const User = { - template: ` -
-

User {{ $route.params.id }}

- -
- `, -} +```vue + + ``` 要将组件渲染到这个嵌套的 `router-view` 中,我们需要在路由中配置 `children`: @@ -128,3 +135,25 @@ const routes = [   }, ] ``` + + +## Omitting parent components + +We can also take advantage of the parent-child relationship between routes without needing to nest route components. This can be useful for grouping together routes with a common path prefix, or when working with more advanced features, such as [per-route navigation guards](../advanced/navigation-guards#Per-Route-Guard) or [route meta fields](../advanced/meta). + +To achieve this, we omit the `component` and `components` options from the parent route: + +```js +const routes = [ + { + path: '/admin', + children: [ + { path: '', component: AdminOverview }, + { path: 'users', component: AdminUserList }, + { path: 'users/:id', component: AdminUserDetails }, + ], + }, +] +``` + +As the parent doesn't specify a route component, the top-level `` will skip over the parent and just use the component from the relevant child instead. diff --git a/packages/docs/zh/guide/essentials/passing-props.md b/packages/docs/zh/guide/essentials/passing-props.md index 1b189ca7..dab41339 100644 --- a/packages/docs/zh/guide/essentials/passing-props.md +++ b/packages/docs/zh/guide/essentials/passing-props.md @@ -5,26 +5,74 @@ title="Learn how to pass props to route components" /> -在你的组件中使用 `$route` 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 `props` 配置来解除这种行为: +在你的组件中使用 `$route` 或 `useRoute()` 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 `props` 配置来解除这种行为: -我们可以将下面的代码 +回到我们之前的示例: + +```vue + + +``` + +和: ```js -const User = { - template: '
User {{ $route.params.id }}
' +import User from './User.vue' + +// 传入 `createRouter` +const routes = [ + { path: '/users/:id', component: User }, +] +``` + +我们可以通过声明 prop 来在 `User.vue` 中删除对 `$route` 的直接依赖: + +::: code-group + +```vue [Composition API] + + + + +``` + +```vue [Options API] + + + + ``` -替换成 +::: + +然后我们可以通过设置 `props: true` 来配置路由将 `id` 参数作为 prop 传递给组件: ```js -const User = { - // 请确保添加一个与路由参数完全相同的 prop 名 - props: ['id'], - template: '
User {{ id }}
' -} -const routes = [{ path: '/user/:id', component: User, props: true }] +const routes = [ + { path: '/user/:id', component: User, props: true } +] ``` 这允许你在任何地方使用该组件,使得该组件更容易重用和测试。 diff --git a/packages/docs/zh/installation.md b/packages/docs/zh/installation.md index e7fb9521..5c6c45f7 100644 --- a/packages/docs/zh/installation.md +++ b/packages/docs/zh/installation.md @@ -1,16 +1,6 @@ # 安装 -## 直接下载 / CDN - -[https://unpkg.com/vue-router@4](https://unpkg.com/vue-router@4) - - - -[Unpkg.com](https://unpkg.com) 提供了基于 npm 的 CDN 链接。上述链接将始终指向 npm 上的最新版本。 你也可以通过像 `https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js` 这样的 URL 来使用特定的版本或 Tag。 - - - -这将把 Vue Router 暴露在一个全局的 `VueRouter` 对象上,例如 `VueRouter.createRouter(...)`。 + ## 包管理器 @@ -53,3 +43,16 @@ pnpm create vue 你需要回答一些关于你想创建的项目类型的问题。如果您选择安装 Vue Router,示例应用还将演示 Vue Router 的一些核心特性。 使用包管理器的项目通常会使用 ES 模块来访问 Vue Router,例如 `import { createRouter } from 'vue-router'`。 + +## 直接下载 / CDN + +[https://unpkg.com/vue-router@4](https://unpkg.com/vue-router@4) + + + +[Unpkg.com](https://unpkg.com) 提供了基于 npm 的 CDN 链接。上述链接将始终指向 npm 上的最新版本。 你也可以通过像 `https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js` 这样的 URL 来使用特定的版本或 Tag。 + + + +这将把 Vue Router 暴露在一个全局的 `VueRouter` 对象上,例如 `VueRouter.createRouter(...)`。 +