Вложенные маршруты
Пользовательский интерфейс реальных приложений обычно представлен многоуровневой иерархией компонентов. Столь же обычно и соответствие сегментов URL некоторой структуре вложенности компонентов, например:
/user/foo/profile /user/foo/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
Используя vue-router
, мы можем с лёгкостью выразить эти взаимоотношения при помощи вложенных путей.
Рассмотрим созданное в предыдущем разделе приложение:
<div id="app">
<router-view></router-view>
</div>
const User = {
template: '<div>Пользователь {{ $route.params.id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
Здесь <router-view>
— это точка, в которой будет отображён компонент, соответствующий маршруту верхнего уровня. Аналогичным образом, отображаемый там компонент может и сам содержать вложенный <router-view>
. Изменим немного шаблон компонента User
:
const User = {
template: `
<div class="user">
<h2>Пользователь {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`
}
Для отображения компонентов в этой вложенной точке, нам понадобится опция children
в конфигурации конструктора VueRouter
:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// при совпадении пути с шаблоном /user/:id/profile
// в <router-view> компонента User будет показан UserProfile
path: 'profile',
component: UserProfile
},
{
// при совпадении пути с шаблоном /user/:id/posts
// в <router-view> компонента User будет показан UserPosts
path: 'posts',
component: UserPosts
}
]
}
]
})
Обратите внимание, что вложенные пути, начинающиеся с /
, считаются корневыми. Это позволяет задействовать вложенную структуру компонентов независимо от структуры URL.
Как вы могли заметить, опция children
принимает обычный массив объектов конфигурации маршрутов, такой же как и сам routes
. Таким образом, вложенность путей в теории по глубине ничем не ограничена.
С текущим кодом, если перейти по пути /user/foo
, внутри компонента User
ничего не будет отображаться, так как не произойдёт совпадения по второй части пути. Может быть, что-то в таких случаях отобразить всё же захочется — тогда стоит указать пустой путь:
const router = new VueRouter({
routes: [
{
path: '/user/:id', component: User,
children: [
// при совпадении пути с шаблоном /user/:id
// в <router-view> компонента User будет показан UserHome
{ path: '', component: UserHome },
// ...остальные вложенные маршруты
]
}
]
})
Рабочую демонстрацию этого примера можно найти здесь.