]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
docs(zh): update zh docs from en and format some en docs (#1350)
authorKim Yang <Kim.Yang.GH@outlook.com>
Fri, 13 May 2022 08:54:49 +0000 (16:54 +0800)
committerGitHub <noreply@github.com>
Fri, 13 May 2022 08:54:49 +0000 (10:54 +0200)
Co-authored-by: edison <daiwei521@126.com>
29 files changed:
docs/.vitepress/components/VueSchoolLink.vue
docs/api/index.md
docs/guide/advanced/navigation-failures.md
docs/guide/advanced/navigation-guards.md
docs/zh/api/index.md
docs/zh/guide/advanced/composition-api.md
docs/zh/guide/advanced/data-fetching.md
docs/zh/guide/advanced/dynamic-routing.md
docs/zh/guide/advanced/extending-router-link.md
docs/zh/guide/advanced/lazy-loading.md
docs/zh/guide/advanced/meta.md
docs/zh/guide/advanced/navigation-failures.md
docs/zh/guide/advanced/navigation-guards.md
docs/zh/guide/advanced/scroll-behavior.md
docs/zh/guide/advanced/transitions.md
docs/zh/guide/essentials/dynamic-matching.md
docs/zh/guide/essentials/history-mode.md
docs/zh/guide/essentials/named-routes.md
docs/zh/guide/essentials/named-views.md
docs/zh/guide/essentials/navigation.md
docs/zh/guide/essentials/nested-routes.md
docs/zh/guide/essentials/passing-props.md
docs/zh/guide/essentials/redirect-and-alias.md
docs/zh/guide/essentials/route-matching-syntax.md
docs/zh/guide/index.md
docs/zh/guide/migration/index.md
docs/zh/index.md
docs/zh/installation.md
docs/zh/introduction.md

index 4a34ac2287167e494be5cacd3b74478ad88ec63b..028434508deb1c48b23ec3d89b319640c974cc25 100644 (file)
@@ -6,17 +6,19 @@
       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 {
index 38e94a661b8cb09e09cef42b928a57b20bfe43e4..6adb520155378ecac44887fb7079dffbe3e5ee83 100644 (file)
@@ -799,8 +799,7 @@ Route record that can be provided by the user when adding routes via the [`route
 - **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)
 
@@ -809,10 +808,7 @@ Route record that can be provided by the user when adding routes via the [`route
 - **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
 
@@ -828,9 +824,7 @@ Route record that can be provided by the user when adding routes via the [`route
 - **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
 
@@ -851,18 +845,19 @@ Route record that can be provided by the user when adding routes via the [`route
 - **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**: 
 
index 28b2db4841fb17e87c03a9267e876d537cf78b93..2c2f9dfef51331c8aefd645e48635ee4829cda48 100644 (file)
@@ -93,7 +93,6 @@ When returning a new location inside of a Navigation Guard, we are triggering a
 ```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
 }
 ```
index 04fe4d63d23c4801b25ce00495f4c700c54349eb..5ce62f01555442b7eddec9c27e5c8efd854c6859 100644 (file)
@@ -201,16 +201,13 @@ const UserDetails = {
     // 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.
   },
 }
index d7d59deea5616b31489f63b5c7fd8314d5932b71..71e4ba0d59511e4c9db81d29c37ee90ba7a96fdc 100644 (file)
@@ -124,7 +124,7 @@ sidebar: auto
 
 ### 示例:将激活的 class 应用在外层元素
 
-有的时候我们可能想把激活的 class 应用到一个外部元素而不是 `<a>` 标签本身,这时你可以在一个 `router-link` 中包裹该元素并使用 `v-slot` 属性来创建链接:
+有我们可能想把激活的 class 应用到一个外部元素而不是 `<a>` 标签本身,这时你可以在一个 `router-link` 中包裹该元素并使用 `v-slot` 属性来创建链接:
 
 ```html
 <router-link
@@ -168,21 +168,21 @@ sidebar: auto
 `<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。
@@ -601,7 +601,7 @@ _参数_
 
 | 参数    | 类型                                                                              | 描述                      |
 | ------- | --------------------------------------------------------------------------------- | ------------------------- |
-| handler | `(error: any, to: RouteLocationNormalized, from: RouteLocationNormalized) => any` | error handler to register |
+| handler | `(error: any, to: RouteLocationNormalized, from: RouteLocationNormalized) => any` | 注册的错误处理程序 |
 
 ### push
 
@@ -816,8 +816,7 @@ stringifyQuery?: (
 - **类型**:`string | string[]` (可选)
 - **详细内容**:
 
-  路由的别名。允许定义类似记录副本的额外路由。这使得路由可以简写为像这种 `/users/:id` 和
-  `/u/:id`。 **所有的 `alias` 和 `path` 值必须共享相同的参数**。
+  路由的别名。允许定义类似记录副本的额外路由。这使得路由可以简写为像这种 `/users/:id` 和 `/u/:id`。 **所有的 `alias` 和 `path` 值必须共享相同的参数**。
 
 ### name
 
@@ -838,10 +837,24 @@ stringifyQuery?: (
 - **类型**:`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) (可选)
@@ -890,7 +903,7 @@ const routes = [{ path: '/', component: HomeView }]
 - **类型**:标准化[路由记录](#routerecordnormalized)数组
 - **详细内容**:
 
-  当前路由的子路由记录。如果没有则为空数组
+  路由被添加时的子路由记录。如果没有则为空数组。注意这个数组在 `addRoute()` 和 `removeRoute()` 被调用时不会更新
 
 ### components
 
index 060e97de14c5ed76d6476b091e0f1cad6a1e1040..bfe18c06a383e210b4ff65a529a827d5a9435e43 100644 (file)
@@ -1,5 +1,10 @@
 # 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` 中访问路由和当前路由
@@ -26,10 +31,11 @@ export default {
 }
 ```
 
-`route` 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该**避免监听整个 `route`** 对象
+`route` 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该**避免监听整个 `route`** 对象。在大多数情况下,你应该直接监听你期望改变的参数。
 
 ```js
 import { useRoute } from 'vue-router'
+import { ref, watch } from 'vue'
 
 export default {
   setup() {
@@ -38,9 +44,9 @@ export default {
 
     // 当参数更改时获取用户信息
     watch(
-      () => route.params,
-      async newParams => {
-        userData.value = await fetchUser(newParams.id)
+      () => route.params.id,
+      async newId => {
+        userData.value = await fetchUser(newId)
       }
     )
   },
@@ -55,6 +61,7 @@ export default {
 
 ```js
 import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
+import { ref } from 'vue'
 
 export default {
   setup() {
@@ -88,6 +95,7 @@ Vue Router 将 RouterLink 的内部行为作为一个组合式 API 函数公开
 
 ```js
 import { RouterLink, useLink } from 'vue-router'
+import { computed } from 'vue'
 
 export default {
   name: 'AppLink',
index 3b999f20548080d461f53f03f216ae15b44927e5..e060fcfb7b4db9d2e811e7bc70d8f249c332a428 100644 (file)
@@ -55,7 +55,6 @@ export default {
       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) {
index b488aad238d9681ed40d2cdd065b017930965b24..70991f16f7bd4e8f8bbde59334d2cd13f0bfb0fb 100644 (file)
@@ -1,5 +1,10 @@
 # 动态路由
 
+<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) )这样的应用程序可以使用它来扩展应用程序。
 
 ## 添加路由
index 4fd95bc67e21d920a14e3eaf4387d133a8a0af0f..b78507bf02c86b713e901986dfc0307a1f2f2033 100644 (file)
@@ -1,5 +1,10 @@
 # 扩展 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`:
@@ -31,6 +36,7 @@ import { RouterLink } from 'vue-router'
 
 export default {
   name: 'AppLink',
+  inheritAttrs: false,
 
   props: {
     // 如果使用 TypeScript,请添加 @ts-ignore
@@ -62,11 +68,8 @@ export default {
   },
 
   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!
 
@@ -89,4 +92,3 @@ export default {
   </AppLink>
 </template>
 ```
-
index e0686f0d93f64106ff91b5eef25959c5956d77fd..099d50cba77672f5f44e16a649b7d8f1e2658b62 100644 (file)
@@ -1,5 +1,10 @@
 # 路由懒加载
 
+<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),这意味着你可以用动态导入代替静态导入:
@@ -37,6 +42,8 @@ const UserDetails = () =>
 
 ## 把组件按组分块
 
+### 使用 webpack
+
 有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用[命名 chunk](https://webpack.js.org/guides/code-splitting/#dynamic-imports),一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4):
 
 ```js
@@ -49,3 +56,26 @@ const UserProfileEdit = () =>
 ```
 
 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',
+          ],
+        },
+    },
+  },
+})
+```
index 076a505e8896a8cd24e4c6f186bb946712688bac..4e1ed64aae434a315833244f23d63a4613bf35bc 100644 (file)
@@ -1,5 +1,10 @@
 # 路由元信息
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/route-meta-fields"
+  title="Learn how to use route meta fields"
+/>
+
 有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的`meta`属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置 `meta` 字段:
 
 ```js
index d688bfd245016653ed24ac1830c0805b6bf5b8bf..1324386645ef4c11c50545426990d9472e321ace 100644 (file)
@@ -1,5 +1,10 @@
 # 等待导航结果
 
+<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` 来触发一次导航。虽然大多数链接的预期行为是将用户导航到一个新页面,但也有少数情况下用户将留在同一页面上:
 
 - 用户已经位于他们正在尝试导航到的页面
index 99d8340e3d14cb98897abe929d4bc78617444e92..703d30867721031feda0d65542c134b2a3850b3c 100644 (file)
@@ -1,5 +1,10 @@
 # 导航守卫
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/route-guards"
+  title="Learn how to add navigation guards"
+/>
+
 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
 
 ## 全局前置守卫
@@ -28,6 +33,19 @@ router.beforeEach((to, from) => {
 - `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`,**则导航是有效的**,并调用下一个导航守卫
@@ -37,7 +55,8 @@ router.beforeEach((to, from) => {
 ```js
 router.beforeEach(async (to, from) => {
   // canUserAccess() 返回 `true` 或 `false`
-  return await canUserAccess(to)
+  const canAccess = await canUserAccess(to)
+  if (!canAccess) return '/login'
 })
 ```
 
index 65d9c28c25629a981ac768e847657af13bbf5c0b..c34d043dbbe444869763e1e26f94cd0c8ff3000a 100644 (file)
@@ -1,4 +1,8 @@
 # 滚动行为
+<VueSchoolLink
+  href="https://vueschool.io/lessons/scroll-behavior"
+  title="Learn how to customize scroll behavior"
+/>
 
 使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。
 
index 9940985fdf7efc3fc0f049f85819d27bac3400c8..4ae53b8aa130d6094b150b2289d123281df8cbe6 100644 (file)
@@ -1,5 +1,10 @@
 # 过渡动效
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/route-transitions"
+  title="Learn about route transitions"
+/>
+
 想要在你的路径组件上使用转场,并对导航进行动画处理,你需要使用 [v-slot API](../../api/#router-view-s-v-slot):
 
 ```html
@@ -10,7 +15,7 @@
 </router-view>
 ```
 
-[Transition 的所有功能](https://v3.vuejs.org/guide/transitions-enterleave.html) 在这里同样适用。
+[Transition 的 API](https://v3.vuejs.org/guide/transitions-enterleave.html) 在这里同样适用。
 
 ## 单个路由的过渡
 
@@ -63,5 +68,17 @@ router.afterEach((to, from) => {
 })
 ```
 
+## 强制在复用的视图之间进行过渡
+
+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). -->
index 70034bf58cc41ef4c0f59fd8ad60d31a710b1c7b..7d0646f1e84c8ccbe006e5725671dd5676656b5b 100644 (file)
@@ -1,5 +1,10 @@
 # 带参数的动态路由匹配
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/dynamic-routes"
+  title="Learn about dynamic route matching with params"
+/>
+
 很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 `User` 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 _路径参数_ :
 
 ```js
@@ -45,6 +50,11 @@ const User = {
 
 ## 响应路由参数的变化
 
+<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` :
@@ -77,6 +87,11 @@ const User = {
 
 ## 捕获所有路由或 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
@@ -93,7 +108,11 @@ const routes = [
 ```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,
 })
 ```
 
index 98a7bd199d06206b76ce429f42851457136f9131..70bc34ffcf047cc128b65ef737536e3acf87bf4b 100644 (file)
@@ -1,5 +1,10 @@
 # 不同的历史模式
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/history-mode"
+  title="Learn about the differences between Hash Mode and HTML5 Mode"
+/>
+
 在创建路由器实例时,`history` 配置允许我们在不同的历史模式中进行选择。
 
 ## Hash 模式
index 1f34933d26e38af8b5d4a2cf052e436f0662e935..6c2fafc638a548abc9c64540d85677027cf1e85d 100644 (file)
@@ -1,5 +1,10 @@
 # 命名路由
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/named-routes"
+  title="Learn about the named routes"
+/>
+
 除了 `path` 之外,你还可以为任何路由提供 `name`。这有以下优点:
 
 - 没有硬编码的 URL
index 4c450449a901035968e94a9a91211bd8294f2945..11e8f5f180b84f4d5af7666c4a0c8a645bd52ff6 100644 (file)
@@ -1,5 +1,10 @@
 # 命名视图
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/vue-router-4-named-views"
+  title="Learn how to use named views"
+/>
+
 有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 `sidebar` (侧导航) 和 `main` (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 `router-view` 没有设置名字,那么默认为 `default`。
 
 ```html
index 1e70fd741e3743784f9ad2177022a136432df5b6..82b1520c04f4715aa5c2fb1b94b2101c1f12117b 100644 (file)
@@ -4,6 +4,11 @@ sidebarDepth: 0
 
 # 编程式导航
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/vue-router-4-programmatic-navigation"
+  title="Learn how to navigate programmatically"
+/>
+
 除了使用 `<router-link>` 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
 
 ## 导航到不同的位置
@@ -51,6 +56,8 @@ router.push({ name: 'user', params: { username } }) // -> /user/eduardo
 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) 中详细介绍。
@@ -73,6 +80,11 @@ router.replace({ path: '/home' })
 
 ## 横跨历史
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/go-back"
+  title="Learn how to use Vue Router to go back"
+/>
+
 该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 `window.history.go(n)`。
 
 例子
@@ -81,7 +93,7 @@ router.replace({ path: '/home' })
 // 向前移动一条记录,与 router.forward() 相同
 router.go(1)
 
-// 返回一条记录,与router.back() 相同
+// 返回一条记录,与 router.back() 相同
 router.go(-1)
 
 // 前进 3 条记录
@@ -98,4 +110,4 @@ router.go(100)
 
 因此,如果你已经熟悉 [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` )都能始终正常工作。
index d7cf37095ab4a3b952eab58b5e1b888a7f8c9117..b7cc1a0cfcd928fdd7fc448a597eb0ee32a21a3e 100644 (file)
@@ -1,5 +1,10 @@
 # 嵌套路由
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/nested-routes"
+  title="Learn about nested routes"
+/>
+
 一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的片段通常对应于特定的嵌套组件结构,例如:
 
 ```
index b4fd96717633cb5215888a829f30ab52a3168afe..0cef8761a2d80fb28b9d7e496d0d4daf23dd645c 100644 (file)
@@ -1,5 +1,10 @@
 # 将 props 传递给路由组件
 
+<VueSchoolLink
+  href="https://vueschool.io/lessons/route-props"
+  title="Learn how to pass props to route components"
+/>
+
 在你的组件中使用 `$route` 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 `props` 配置来解除这种行为:
 
 我们可以将下面的代码
@@ -15,6 +20,7 @@ const routes = [{ path: '/user/:id', component: User }]
 
 ```js
 const User = {
+  // 请确保添加一个与路由参数完全相同的 prop 名
   props: ['id'],
   template: '<div>User {{ id }}</div>'
 }
@@ -72,5 +78,3 @@ const routes = [
 URL `/search?q=vue` 将传递 `{query: 'vue'}` 作为 props 传给 `SearchUser` 组件。
 
 请尽可能保持 `props` 函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 vue 才可以对状态变化做出反应。
-
-高级使用方法,请查看[示例](https://github.com/vuejs/vue-router/blob/dev/examples/route-props/app.js).
index feaba513fdb65bf875a501575911905bb674c426..aa28a0eeb94bd23335aab9fb254a96dc331fc06d 100644 (file)
@@ -1,10 +1,14 @@
 # 重定向和别名
 
+<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: '/' }]
 ```
@@ -46,10 +50,13 @@ const routes = [
 ```js
 const routes = [
   {
+    // 将总是把/users/123/posts重定向到/users/123/profile。
     path: '/users/:id/posts',
     redirect: to => {
-      // 方法接收目标路由作为参数
-      // return 重定向的字符串路径/路径对象
+      // 该函数接收目标路由作为参数
+      // 相对位置不以`/`开头
+      // 或 { path: 'profile'}
+      return 'profile'
     },
   },
 ]
index 65d359f3132439bf27aa08969c72cebf39d0cd26..67be20e4bc12c65202140e9941057713d3b49666 100644 (file)
@@ -1,5 +1,10 @@
 # 路由的匹配语法
 
+<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
@@ -75,6 +80,25 @@ const routes = [
 ]
 ```
 
+## 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 个)将一个参数标记为可选:
index 99a28f602d90ebf92475116a66ae5228a11eb49d..5c4232a530d532735dac7293e32719ad323f5a87 100644 (file)
@@ -1,5 +1,10 @@
 # 入门
 
+<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
index e8cb932e3884469cfecdb3db3308e0d13eb3d71f..554c9d139ca3794b3897bfe8ce83c16c1732edd9 100644 (file)
@@ -67,7 +67,7 @@ createRouter({
 })
 ```
 
-### 删除了 `RouterOptions` 中的 `fallback` 属性
+### 删除了 `fallback` 属性
 
 创建路由时不再支持 `fallback` 属性:
 
@@ -365,16 +365,20 @@ const routes = [
   {
     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'
@@ -410,6 +414,7 @@ const routes = [
 
 给定任何[规范化的路由地址](../../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`。
index 5172dc0406b800b4953015ae0ad8b91cce4ac083..9f916d5d33669d80ae9605146a447099463d922b 100644 (file)
@@ -1,8 +1,25 @@
 ---
 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
 ---
index 0c5c1d9b482a7e756adc7c9d83f52ec15aa4cf67..335b8ce0231a72e6874a2ea22732f1313fb31af2 100644 (file)
 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
index 823de735904c2a0e7d9547671f77427a21947859..dc50c9924990b119263b6ba1b9762442fc8cc855 100644 (file)
@@ -1,5 +1,10 @@
 # 介绍
 
+<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 构建单页应用变得轻而易举。功能包括:
 
 - 嵌套路由映射