12. Exemplo [nuxt-09]: controlo da navegação
O exemplo [nuxt-09] utiliza um middleware para controlar a navegação do cliente. Além disso, é adicionada uma nova vista para os casos em que o utilizador solicita ao servidor um URL que não existe na aplicação.
O exemplo [nuxt-09] é inicialmente obtido por cópia do exemplo [nuxt-01]:

12.1. A página [_.vue]
Já referimos que as rotas da aplicação são construídas a partir do conteúdo da pasta [pages]. Aqui, adicionámos a esta pasta a página [_.vue]. Esta página específica é apresentada sempre que a aplicação é redirecionada para uma página que não existe. No nosso exemplo, isto não pode acontecer para o cliente. Mas pode acontecer para o servidor se, por exemplo, lhe for solicitada a página URL [/nuxt-09/abcd]. Como a página [abcd] não existe, será apresentada a página [_.vue]. Neste caso, será a seguinte:

O código da página [_.vue] é o seguinte:
<!-- definição HTML da vista -->
<template>
<!-- formatação -->
<Layout :left="true" :right="true">
<!-- alerta na coluna da direita -->
<template slot="right">
<!-- mensagem sobre fundo amarelo -->
<b-alert show variant="warning" align="center">
<h4>La page demandée n'existe pas</h4>
</b-alert>
</template>
<!-- menu de navegação na coluna da esquerda -->
<Navigation slot="left" />
</Layout>
</template>
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
import Layout from '@/components/layout'
import Navigation from '@/components/navigation'
export default {
name: '404',
// componentes utilizados
components: {
Layout,
Navigation
},
// ciclo de vida
beforeCreate() {
// cliente e servidor
console.log('[404 beforeCreate]')
},
created() {
// cliente e servidor
console.log('[404 created]')
},
beforeMount() {
// apenas cliente
console.log('[404 beforeMount]')
},
mounted() {
// apenas cliente
console.log('[404 mounted]')
}
}
</script>
12.2. O middleware do cliente
O código do middleware do cliente [client-routing] é o seguinte:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function({ route, from, redirect }) {
// apenas o cliente
if (process.client) {
console.log('[client-routing]')
// ordem de navegação pretendida
const routes = ['index', 'page1', 'page2', 'index']
// rota atual
const current = route.name
// rota anterior
const previous = from.name
// pretende-se uma navegação circular
// rotas[i] para rotas[i+1]
for (let i = 0; i < routes.length - 1; i++) {
if (previous === routes[i] && current !== routes[i + 1]) {
// permanecemos na mesma página
redirect({ name: routes[i] })
return
}
}
}
}
- linha 3: sabemos que a função de encaminhamento recebe apenas um parâmetro, o objeto [context] daquele que a executa, seja o servidor ou o cliente. A notação [function({ route, from, redirect })]
- é equivalente a [function({ route:route, from:from, redirect:redirect })];
- o que faz com que { route:route, from:from, redirect:redirect } <-- contexto;
- o que cria três parâmetros [route, from, redirect], tais como:
- route=context.route;
- redirect=context.redirect;
- from=context.from;
A documentação do [nuxt] utiliza amplamente esta notação. É necessário conhecê-la;
- linha 8: uma tabela com os nomes das páginas na ordem de navegação pretendida
- linha 10: o nome da página de destino do encaminhamento atual;
- linha 12: o nome da página anterior do percurso atual;
- linha 14: como exercício, vamos permitir apenas uma navegação circular [index --> page1 --> page2 --> index];
- linhas 15-21: percorremos a tabela que indica a ordem de navegação pretendida;
- linha 16: se se verificar que routes[i] foi a última página encaminhada, então a seguinte deve ser routes[i+1];
- linhas 18-19: se não for esse o caso, redireciona-se a aplicação para routes[i], ou seja, não se muda de página: recusa-se a navegação;
12.3. Exécution
Executa-se o exemplo com o seguinte ficheiro [nuxt.config.js]:
export default {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: process.env.npm_package_name || "Introduction à nuxt.js par l'exemple",
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: [],
/*
** Plugins to load before mounting the App
*/
plugins: [],
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'@nuxtjs/eslint-module'
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://bootstrap-vue.js.org
'bootstrap-vue/nuxt',
// Documentação: https://axios.nuxtjs.org/usage
'@nuxtjs/axios'
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {}
},
// diretório do código-fonte
srcDir: 'nuxt-09',
router: {
base: '/nuxt-09/',
middleware: ['client-routing']
},
// servidor
server: {
port: 81, // padrão: 3000
host: 'localhost' // padrão: localhost
}
}
Verifique os seguintes pontos:
- quando estiver na página [Home], só pode navegar para a página [Page 1];
- quando estiver na página [Page 1], só pode navegar para a página [Page 2];
- quando estiver na página [Page 2], só pode navegar para a página [Home];
- quando solicitar uma URL incorreta, como [http://localhost:81/nuxt-09b/abcd], obtém uma mensagem a indicar que a página solicitada não existe;