11. Exemplo [nuxt-08]: Middleware de roteamento
Neste exemplo, apresentamos o conceito de middleware de roteamento, scripts executados sempre que uma rota muda.
O Exemplo [nuxt-08] é inicialmente criado através da clonagem do projeto [nuxt-01]:

O middleware de roteamento deve ser colocado numa pasta chamada [middleware] [2]. Pode haver um roteamento de dois níveis:
- roteamento aplicado a todas as navegações. Este é então declarado no ficheiro [nuxt.config.js];
- roteamento aplicado a uma página específica, quando essa página é o destino do roteamento. Este roteamento é então declarado nessa página de destino;
11.1. Roteamento Geral
O ficheiro [middleware/routing.js] irá tratar do encaminhamento geral. É declarado da seguinte forma no ficheiro [nuxt.config.js]:
router: {
base: '/nuxt-08/',
middleware: ['routing']
},
O middleware de roteamento geral é uma propriedade do router (linha 1). Pode haver vários componentes de middleware de roteamento. É por isso que, na linha 3, o valor da propriedade [middleware] é uma matriz. Note que não usamos um caminho para especificar o middleware. Ele será procurado automaticamente na pasta [middleware] do projeto;
O middleware [routing] apenas regista aqui:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// who executes this code?
console.log('[routing], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const routing = '[routing ' + who + ']'
// number of arguments
console.log(routing + ', il y a', args.length, 'argument(s)')
// 1st argument
const context = args[0]
// key context
dumpkeys(routing + ', context', context)
// the application
dumpkeys(routing + ', context.app', context.app)
// the road
dumpkeys(routing + ', context.route', context.route)
console.log(routing + ', context.route=', context.route)
// the router
dumpkeys(routing + ', context.app.router', context.app.router)
// on router.options.routes
dumpkeys(routing + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(routing + ', context.app.router.options.routes=', context.app.router.options.routes)
}
function dumpkeys(message, object) {
// list of [object] keys
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// kEY LIST
if (object) {
console.log(Object.keys(object))
}
}
- linha 3: veremos que o middleware recebe um argumento: o contexto do executor (servidor ou cliente);
- linhas 4–25: exibimos as propriedades de vários objetos para determinar o que é utilizável. Veremos que o contexto do middleware é quase idêntico ao contexto do plugin;
11.2. Roteamento para uma página específica
Queremos controlar como os utilizadores chegam à página [index]. Para isso, precisamos de adicionar a propriedade [middleware] a esta página [index]:
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
import Navigation from '@/components/navigation'
import Layout from '@/components/layout'
export default {
name: 'Home',
// components used
components: {
Layout,
Navigation
},
// life cycle
beforeCreate() {
// client and server
console.log('[home beforeCreate]')
},
created() {
// client and server
console.log('[home created]')
},
beforeMount() {
// customer only
console.log('[home beforeMount]')
},
mounted() {
// customer only
console.log('[home mounted]')
},
// routing
middleware: ['index-routing']
}
</script>
- linha 34: a propriedade [middleware] lista os scripts a serem executados sempre que a próxima página exibida for a página [index]. Mais uma vez, estes scripts serão procurados na pasta [middleware] do projeto;
O middleware [index-routing] é o seguinte:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// who executes this code?
console.log('[index-routing], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const indexRouting = '[index-routing ' + who + ']'
// number of arguments
console.log(indexRouting + ', il y a', args.length, 'argument(s)')
// 1st argument
const context = args[0]
// key context
dumpkeys(indexRouting + ', context', context)
// the application
dumpkeys(indexRouting + ', context.app', context.app)
// the road
dumpkeys(indexRouting + ', context.route', context.route)
console.log(indexRouting + ', context.route=', context.route)
// the router
dumpkeys(indexRouting + ', context.app.router', context.app.router)
// on router.options.routes
dumpkeys(indexRouting + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(indexRouting + ', context.app.router.options.routes=', context.app.router.options.routes)
// where do we come from?
if (context.from) {
console.log('from=', context.from)
}
}
function dumpkeys(message, object) {
// list of [object] keys
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// kEY LIST
if (object) {
console.log(Object.keys(object))
}
}
O código para [index-routing] é idêntico ao de [routing] e produz os mesmos resultados. O que nos interessa é ver quando estes dois middlewares são executados.
11.3. Executar o projeto
Executamos o projeto. Os registos são os seguintes:
O script [routing] é executado primeiro pelo servidor:
Este é o mesmo resultado que obtivemos com os plugins.
- linha 15: a propriedade [redirect] é frequentemente utilizada em middleware; permite alterar o destino do encaminhamento atual;
Então, como a página a ser exibida é a página [index], o servidor executa o script [index-routing] e exibe os seguintes registos:
Os resultados obtidos com o script [index-routing] são semelhantes aos obtidos com o script [routing].
Assim que a página [index] é recebida pelo navegador do cliente, os scripts do cliente assumem o controlo. Os registos ficam da seguinte forma:
Podemos ver, portanto, que quando a aplicação é iniciada, o cliente não executa nenhum middleware. Isto significa que isto acontecerá sempre que o utilizador forçar um pedido ao servidor. O middleware só é executado pelo cliente quando se navega dentro do cliente. Por exemplo, vamos navegar para a página [page1] (estamos atualmente na página [index]) utilizando o link [Page 1]. Os registos são então os seguintes:
- linha 2: o middleware [routing] é executado pelo cliente;
- linha 4: repare na propriedade [from]: esta é a rota de onde viemos;
- linha 9: [context.route] é a rota para onde nos dirigimos;
- linhas 15–18: exibição da página [page1];
Agora, vamos voltar à página [index] utilizando o link [Home]. Os registos ficam então assim:
- linhas 1-15: o cliente executa o middleware [routing]. Isto é normal. É executado sempre que a rota muda;
- linhas 16–29: o cliente executa o middleware [index-routing], porque:
- [index] é o destino da rota atual (ver linha 23);
- a página [index] definiu um middleware chamado [index-routing];
Podemos ver, então, que o middleware de roteamento geral é executado pelo cliente antes do middleware associado às páginas.