Rotas Encaixadas
Algumas UIs da aplicação são compostas de componentes que são encaixados vários níveis de profundidade. Neste caso, é muito comum que os segmentos de uma URL corresponda à uma certa estrutura de componentes encaixados, por exemplo:
/user/johnny/profile /user/johnny/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
/user/johnny/profile /user/johnny/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
Com a Vue Router, podes expressar este relacionamento usando as configurações de rota encaixada.
Dada a aplicação que criamos no último capítulo:
<div id="app">
<router-view></router-view>
</div>
<div id="app">
<router-view></router-view>
</div>
const User = {
template: '<div>User {{ $route.params.id }}</div>',
}
// estas rotas são passadas para o `createRouter`
const routes = [{ path: '/user/:id', component: User }]
const User = {
template: '<div>User {{ $route.params.id }}</div>',
}
// estas rotas são passadas para o `createRouter`
const routes = [{ path: '/user/:id', component: User }]
O <router-view>
aqui é um router-view
de alto nível. Ele apresenta o componente correspondido por uma rota de alto nível. Similarmente, o componente apresentado também pode conter o seu próprio, <router-view>
encaixado. Por exemplo, se adicionarmos um dentro do modelo de marcação do componente User
:
const User = {
template: `
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`,
}
const User = {
template: `
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`,
}
Para apresentar os componentes dentro deste router-view
encaixado, precisamos usar a opção children
em quaisquer das rotas:
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
/*
UserProfile será apresentado dentro do <router-view> do User
quando `/user/:id/profile` for correspondido
*/
path: 'profile',
component: UserProfile,
},
{
/*
UserPosts será apresentado dentro do <router-view> do User
quando `/user/:id/posts` for correspondido
*/
path: 'posts',
component: UserPosts,
},
],
},
]
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
/*
UserProfile será apresentado dentro do <router-view> do User
quando `/user/:id/profile` for correspondido
*/
path: 'profile',
component: UserProfile,
},
{
/*
UserPosts será apresentado dentro do <router-view> do User
quando `/user/:id/posts` for correspondido
*/
path: 'posts',
component: UserPosts,
},
],
},
]
Nota que caminhos encaixados que começam com /
serão tratados como um caminho de raiz. Isto permite-te influenciar o encaixamento do componente sem ter de usar uma URL encaixada.
Conforme podes ver a opção children
é apenas um outro arranjo de rotas como o próprio routes
. Portanto, podes continuar a encaixar as visões tanto quanto precisares.
Até este ponto, com a configuração acima, quando visitas /user/eduardo
, nada será apresentado dentro da router-view
do User
, porque nenhuma rota encaixada é correspondida. Talvez queiras apresentar alguma coisa lá. Em tal caso podes fornecer um caminho encaixado vazio:
const routes = [
{
path: '/user/:id',
component: User,
children: [
/*
UserHome será apresentado dentro da `<router-view>` do User
quando `/user/:id` for correspondido
*/
{ path: '', component: UserHome },
// ...outras sub-rotas
],
},
]
const routes = [
{
path: '/user/:id',
component: User,
children: [
/*
UserHome será apresentado dentro da `<router-view>` do User
quando `/user/:id` for correspondido
*/
{ path: '', component: UserHome },
// ...outras sub-rotas
],
},
]
Uma demonstração em funcionamento deste exemplo pode ser encontrada nesta ligação.
Rotas Encaixadas Nomeadas
Quando estamos a lidar com Rotas Nomeadas, normalmente nomeias as rotas filhas:
const routes = [
{
path: '/user/:id',
component: User,
// repara em como apenas a rota filha tem um nome
children: [{ path: '', name: 'user', component: UserHome }],
},
]
const routes = [
{
path: '/user/:id',
component: User,
// repara em como apenas a rota filha tem um nome
children: [{ path: '', name: 'user', component: UserHome }],
},
]
Isto garantira que a navegação para /user/:id
sempre exibirá a rota encaixada.
Em alguns cenários, podes querer navegar para uma rota nomeada sem navegar para a rota encaixada. Por exemplo, se quiseres navegar para /user/:id
sem exibir a rota encaixada. Neste caso, também podes nomear a rota pai mas nota que ao recarregar a página sempre exibirá a filha encaixada já que é considerada uma navegação para o caminho /users/:id
ao invés da rota nomeada:
const routes = [
{
path: '/user/:id',
name: 'user-parent'
component: User,
children: [{ path: '', name: 'user', component: UserHome }],
},
]
const routes = [
{
path: '/user/:id',
name: 'user-parent'
component: User,
children: [{ path: '', name: 'user', component: UserHome }],
},
]