Skip to content
Перевод синхронизирован с документацией от , хэш коммита 960662d.

Вложенные маршруты

Некоторые пользовательские интерфейсы приложений состоят из вложенных на нескольких уровнях компонентов. В этом случае часто бывает так, что сегменты 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'

// маршруты передаются в `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 будет отрендерен внутри <router-view> компонента User
        // при соответствии /user/:id/profile
        path: 'profile',
        component: UserProfile,
      },
      {
        // UserPosts будет отрендерен внутри <router-view> компонента User
        // при соответствии /user/:id/posts
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]

Обратите внимание, что вложенные пути, начинающиеся с /, будут рассматриваться как корневые. Это позволяет вам использовать вложенность компонентов без необходимости использовать вложенного URL.

Как видите, опция children представляет собой еще один массив маршрутов, подобно самим routes. Следовательно, вы можете вкладывать представления насколько вам нужно.

На этом этапе, при посещении /user/eduardo, внутри router-view компонента User рендерится ничего не будет, потому что не будет совпадать ни один вложенный маршрут. Возможно, вы хотите что-то отображать там. В таком случае вы можете предоставить пустой вложенный путь:

js
const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      // UserHome будет отрендерен внутри <router-view> компонента User
      // при соответствии /user/:id
      { path: '', component: UserHome },

      // ...другие вложенные маршруты
    ],
  },
]

Рабочее демо этого примера можно найти здесь.

Вложенные именованные маршруты

При работе с Именованными маршрутами обычно именуют дочерние маршруты:

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 }],
  },
]

Исключение родительских компонентов 4.1+

Мы также можем воспользоваться отношением родитель-потомок между маршрутами, не обязательно вкладывая компоненты маршрутов друг в друга. Это может быть полезно для группировки маршрутов с общим префиксом пути или при работе с более продвинутыми функциями, такими как навигационные хуки на уровне маршрута или метаданные маршрута.

Для этого мы опускаем опции component и components из родительского маршрута:

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

Поскольку родительский маршрут не указывает компонент маршрута, <router-view> верхнего уровня пропустит компонент родителя и просто использует компонент из соответствующего дочернего маршрута.

Released under the MIT License.