Skip to content
该翻译已同步到了 的版本,其对应的 commit hash 是 d842b6f

嵌套路由

一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的片段通常对应于特定的嵌套组件结构,例如:

/user/johnny/profile                   /user/johnny/posts 
┌──────────────────┐                  ┌──────────────────┐
│ User             │                  │ User             │
│ ┌──────────────┐ │                  │ ┌──────────────┐ │
│ │ Profile      │ │  ●────────────▶  │ │ Posts        │ │
│ │              │ │                  │ │              │ │
│ └──────────────┘ │                  │ └──────────────┘ │
└──────────────────┘                  └──────────────────┘

通过 Vue Router,你可以使用嵌套路由配置来表达这种关系。

接着上节创建的 app :

vue
<!-- App.vue -->
<template>
  <router-view />
</template>
vue
<!-- User.vue -->
<template>
  <div>
    User {{ $route.params.id }}
  </div>
</template>
js
import User from './User.vue'

// 这些都会传递给 `createRouter`
const routes = [{ path: '/user/:id', component: User }]

这里的 <router-view> 是一个顶层的 router-view。它渲染顶层路由匹配的组件。同样地,一个被渲染的组件也可以包含自己嵌套的 <router-view>。例如,如果我们在 User 组件的模板内添加一个 <router-view>

vue
<!-- User.vue -->
<template>
  <div class="user">
    <h2>User {{ $route.params.id }}</h2>
    <router-view />
  </div>
</template>

要将组件渲染到这个嵌套的 router-view 中,我们需要在路由中配置 children

js
const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        // 当 /user/:id/profile 匹配成功
        // UserProfile 将被渲染到 User 的 <router-view> 内部
        path: 'profile',
        component: UserProfile,
      },
      {
        // 当 /user/:id/posts 匹配成功
        // UserPosts 将被渲染到 User 的 <router-view> 内部
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]

注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL。

如你所见,children 配置只是另一个路由数组,就像 routes 本身一样。因此,你可以根据自己的需要,不断地嵌套视图。

此时,按照上面的配置,当你访问 /user/eduardo 时,在 Userrouter-view 里面什么都不会呈现,因为没有匹配到嵌套路由。也许你确实想在那里渲染一些东西。在这种情况下,你可以提供一个空的嵌套路径:

js
const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      // 当 /user/:id 匹配成功
      // UserHome 将被渲染到 User 的 <router-view> 内部
      { path: '', component: UserHome },

      // ...其他子路由
    ],
  },
]

这个例子的 demo 可以在这里找到。

嵌套的命名路由

在处理命名路由时,你通常会给子路由命名

js
const routes = [
  {
    path: '/user/:id',
    component: User,
    // 请注意,只有子路由具有名称
    children: [{ path: '', name: 'user', component: UserHome }],
  },
]

这将确保导航到 /user/:id 时始终显示嵌套路由。

在一些场景中,你可能希望导航到命名路由而不导航到嵌套路由。例如,你想导航 /user/:id 而不显示嵌套路由。那样的话,你还可以命名父路由,但请注意重新加载页面将始终显示嵌套的子路由,因为它被视为指向路径/users/:id 的导航,而不是命名路由:

js
const routes = [
  {
    path: '/user/:id',
    name: 'user-parent',
    component: User,
    children: [{ path: '', name: 'user', component: UserHome }],
  },
]

Omitting parent components 4.1+

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 or route meta fields.

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 <router-view> will skip over the parent and just use the component from the relevant child instead.

Released under the MIT License.