Roteamento do Sistema de Ficheiro
A Nuxt gera automaticamente a configuração da vue-router
baseada na nossa árvore de ficheiros .vue
no diretório de páginas. Quando criamos um ficheiro .vue
no nosso diretório de páginas, teremos o roteamento básico a funcionar sem necessidade de configuração adicional.
Por vezes, podemos precisar de criar rotas dinâmicas ou rotas encaixadas, ou podemos precisar de configurar melhor a propriedade do roteador. Este capítulo aborda tudo o que é necessário saber para tirar o máximo partido do nosso roteador.
NuxtLink
para navegar entre as páginas.<template>
<NuxtLink to="/">Home page</NuxtLink>
</template>
Rotas Básicas
Esta árvore de ficheiro:
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
gerará automaticamente:
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'user',
path: '/user',
component: 'pages/user/index.vue'
},
{
name: 'user-one',
path: '/user/one',
component: 'pages/user/one.vue'
}
]
}
Rotas Dinâmicas
Por vezes, não é possível saber o nome da rota, por exemplo, quando fazemos uma chamada a uma interface de programação de aplicação para obter uma lista de utilizadores ou de publicações do blogue. Chamamos-lhes de rotas dinâmicas. Para criar uma rota dinâmica, precisamos adicionar um sublinhado (_
) antes do nome do ficheiro .vue
, ou antes, do nome do diretório. Podemos dar ao ficheiro ou diretório o nome que quisermos, mas temos de o prefixar com um sublinhado.
Esta árvore de ficheiro:
pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue
gerará automaticamente:
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
},
{
name: 'slug',
path: '/:slug',
component: 'pages/_slug/index.vue'
},
{
name: 'slug-comments',
path: '/:slug/comments',
component: 'pages/_slug/comments.vue'
}
]
}
users-id
tem o caminho :id?
o que o torna opcional, se quisermos torná-la obrigatória, criamos um ficheiro index.vue
no diretório users/_id
.Acessar Localmente os Parâmetros da Rota
Podemos acessar aos parâmetros atuais da rota na nossa página ou componente local referenciando this.$route.params.{parameterName}
. Por exemplo, se tivéssemos uma página dinâmica de utilizadores (users/_id.vue
) e quiséssemos acessar ao parâmetro id
para carregar a informação do utilizador ou do processo, poderíamos acessar à variável desta maneira this.$route.params.id
.
Rotas Encaixadas
A Nuxt permite-nos criar rotas encaixadas usando as rotas filhas da vue-router
. Para definir o componente principal duma rota encaixada, precisamos de criar um ficheiro .vue
com o mesmo nome que o diretório que contém as nossas visões filhas.
NuxtChild
dentro do componente pai (ficheiro .vue
).Esta árvore de ficheiro:
pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue
gerará automaticamente:
router: {
routes: [
{
path: '/users',
component: 'pages/users.vue',
children: [
{
path: '',
component: 'pages/users/index.vue',
name: 'users'
},
{
path: ':id',
component: 'pages/users/_id.vue',
name: 'users-id'
}
]
}
]
}
Rotas Dinâmicas Encaixadas
Este não é um cenário comum, mas é possível com a Nuxt ter filhos dinâmicos dentro de pais dinâmicos.
Esta árvore de ficheiro:
pages/
--| _category/
-----| _subCategory/
--------| _id.vue
--------| index.vue
-----| _subCategory.vue
-----| index.vue
--| _category.vue
--| index.vue
gerará automaticamente:
router: {
routes: [
{
path: '/',
component: 'pages/index.vue',
name: 'index'
},
{
path: '/:category',
component: 'pages/_category.vue',
children: [
{
path: '',
component: 'pages/_category/index.vue',
name: 'category'
},
{
path: ':subCategory',
component: 'pages/_category/_subCategory.vue',
children: [
{
path: '',
component: 'pages/_category/_subCategory/index.vue',
name: 'category-subCategory'
},
{
path: ':id',
component: 'pages/_category/_subCategory/_id.vue',
name: 'category-subCategory-id'
}
]
}
]
}
]
}
Rotas Encaixadas Dinâmicas Desconhecidas
Se não soubermos a profundidade da nossa estrutura de endereço de localização de recurso, podemos usar _.vue
para combinar dinamicamente caminhos encaixados. Isto lidará com os pedidos que não correspondem a uma rota mais específica.
Esta árvore de ficheiro:
pages/
--| people/
-----| _id.vue
-----| index.vue
--| _.vue
--| index.vue
gerará automaticamente:
/ -> index.vue
/people -> people/index.vue
/people/123 -> people/_id.vue
/about -> _.vue
/about/careers -> _.vue
/about/careers/chicago -> _.vue
_.vue
.Estender o Roteador
Existem várias maneiras de estender o roteamento com a Nuxt:
-
router-extras-module
para personalizar os parâmetros de rota na página. -
@nuxtjs/router
para sobrescrever o roteador da Nuxt e escrever o nosso próprio ficheirorouter.js
. -
Usar a propriedade
router.extendRoutes
no nossonuxt.config.js
.
A Propriedade router
A propriedade router
permite-nos personalizar o roteador (vue-router
) da Nuxt:
export default {
router: {
// personalizar o roteador da Nuxt
}
}
base
O endereço de localização de recurso de base da aplicação. Por exemplo, se toda a aplicação de página única for servida sob /app/
, então a base deve usar o valor '/app/'
.
extendRoutes
Podemos querer estender as rotas criadas pela Nuxt. Podemos fazer isto através da opção extendRoutes
.
Exemplo de adição duma rota personalizada:
export default {
router: {
extendRoutes(routes, resolve) {
routes.push({
name: 'custom',
path: '*',
component: resolve(__dirname, 'pages/404.vue')
})
}
}
}
Se quisermos organizar as nossas rotas, podemos utilizar a função sortRoutes(routes)
de @nuxt/utils
:
import { sortRoutes } from '@nuxt/utils'
export default {
router: {
extendRoutes(routes, resolve) {
// Adicionar algumas rotas abaixo ...
// e depois organizá-las
sortRoutes(routes)
}
}
}
vue-router
.chunkNames
correspondentes dos components
nomeados.export default {
router: {
extendRoutes(routes, resolve) {
routes.push({
path: '/users/:id',
components: {
default: resolve(__dirname, 'pages/users'), // or routes[index].component
modal: resolve(__dirname, 'components/modal.vue')
},
chunkNames: {
modal: 'components/modal'
}
})
}
}
}
fallback
Controla se o roteador deve retroceder ao modo normal quando o navegador não suportar history.pushState
, mas o modo está definido para history
.
mode
Configura o modo do roteador, não é recomendável alterá-lo devida à interpretação do lado do servidor.
parseQuery
/ stringifyQuery
Fornece as funções parseQuery
ou stringifyQuery
da consulta personalizada.
routeNameSplitter
Podemos querer alterar o separador entre os nomes da rota que a Nuxt utiliza. Podemos fazer isto através da opção routeNameSplitter
no nosso ficheiro de configuração. Imaginemos que temos o ficheiro de página pages/posts/_id.vue
. A Nuxt gerará no nome da rota programaticamente, neste caso posts-id
. Alterar a configuração da routeNameSplitter
para /
o nome mudará para posts/id
:
export default {
router: {
routeNameSplitter: '/'
}
}
scrollBehavior
A opção scrollBehavior
nos permite definir um comportamento personalizado para a posição do deslocamento entre as rotas. Este método é chamado sempre que uma página é desenhada.
scrollBehavior
da vue-router
.Disponível desde a versão 2.9.0:
Na Nuxt, podemos utilizar um ficheiro para sobrescrever o scrollBehavior
do roteador. Este ficheiro deve ser colocado numa pasta chamada app
.
~/app/router.scrollBehavior.js
.
Exemplo de como forçar a posição do deslocação para o topo em todas as rotas:
export default function (to, from, savedPosition) {
return { x: 0, y: 0 }
}
trailingSlash
Disponível desde a versão: 2.10
Se esta opção for definida como verdadeira, serão acrescentadas barras oblíquas ao final de todas as rotas. Se for definida como falso, serão removidas:s
export default {
router: {
trailingSlash: true
}
}
router.trailingSlash
para algo diferente de undefined
(o qual é o valor predefinido), a rota oposta deixará de funcionar. Assim, os redirecionamentos de código 301 devem estar em vigor e a nossa hiperligação interna tem de ser adaptada corretamente. Se definirmos trailingSlash
com true
, então apenas example.com/abc/
funcionará, mas não example.com/abc
. No falso, é vise-versa.











































