跳至内容

嵌套路由

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

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

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

假设我们创建了上一章中的应用程序

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

// these are passed to `createRouter`
const routes = [{ path: '/user/:id', component: User }]

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

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: [
      {
        // UserProfile will be rendered inside User's <router-view>
        // when /user/:id/profile is matched
        path: 'profile',
        component: UserProfile,
      },
      {
        // UserPosts will be rendered inside User's <router-view>
        // when /user/:id/posts is matched
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]

请注意,以 / 开头的嵌套路径将被视为根路径。这使您能够利用组件嵌套,而无需使用嵌套 URL。

如您所见,children 选项只是另一个路由数组,就像 routes 本身一样。因此,您可以根据需要继续嵌套视图。

此时,使用上述配置,当您访问 /user/eduardo 时,Userrouter-view 中不会渲染任何内容,因为没有匹配的嵌套路由。也许您确实想在那里渲染一些内容。在这种情况下,您可以提供一个空的嵌套路径

js
const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      // UserHome will be rendered inside User's <router-view>
      // when /user/:id is matched
      { path: '', component: UserHome },

      // ...other sub routes
    ],
  },
]

可以在 此处找到此示例的工作演示。

嵌套命名路由

在处理 命名路由 时,您通常会为子路由命名

js
const routes = [
  {
    path: '/user/:id',
    component: User,
    // notice how only the child route has a name
    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 }],
  },
]

省略父组件 4.1+

我们还可以利用路由之间的父子关系,而无需嵌套路由组件。这对于将具有公共路径前缀的路由分组在一起或在使用更高级功能(例如 每个路由导航守卫路由元字段)时很有用。

要实现这一点,我们从父路由中省略 componentcomponents 选项

js
const routes = [
  {
    path: '/admin',
    children: [
      { path: '', component: AdminOverview },
      { path: 'users', component: AdminUserList },
      { path: 'users/:id', component: AdminUserDetails },
    ], 
  },
]

由于父级没有指定路由组件,因此顶级 <router-view> 将跳过父级,而只使用相关子级的组件。