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 criado através da cópia do Exemplo [nuxt-01]:

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

O código da página [_.vue] é o seguinte:
<!-- définition HTML de la vue -->
<template>
<!-- mise en page -->
<Layout :left="true" :right="true">
<!-- alerte dans la colonne de droite -->
<template slot="right">
<!-- message sur fond jaune -->
<b-alert show variant="warning" align="center">
<h4>La page demandée n'existe pas</h4>
</b-alert>
</template>
<!-- menu de navigation dans la colonne de gauche -->
<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',
// components used
components: {
Layout,
Navigation
},
// life cycle
beforeCreate() {
// client and server
console.log('[404 beforeCreate]')
},
created() {
// client and server
console.log('[404 created]')
},
beforeMount() {
// customer only
console.log('[404 beforeMount]')
},
mounted() {
// customer only
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 }) {
// seulement le client
if (process.client) {
console.log('[client-routing]')
// ordre de navigation souhaité
const routes = ['index', 'page1', 'page2', 'index']
// route courante
const current = route.name
// route précédente
const previous = from.name
// on veut une navigation circulaire
// routes[i] vers routes[i+1]
for (let i = 0; i < routes.length - 1; i++) {
if (previous === routes[i] && current !== routes[i + 1]) {
// on reste sur la même page
redirect({ name: routes[i] })
return
}
}
}
}
- Linha 3: Sabemos que a função de roteamento aceita apenas um parâmetro, o objeto [context] da entidade 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 significa que { route:route, from:from, redirect:redirect } <-- contexto;
- o que cria três parâmetros [route, from, redirect] como:
- route=context.route;
- redirect=context.redirect;
- from=context.from;
A documentação [nuxt] faz uso extensivo desta notação. É importante estar familiarizado com ela;
- linha 8: um array de nomes de páginas na ordem de navegação desejada
- linha 10: o nome da página de destino para a rota atual;
- linha 12: o nome da página anterior no roteamento atual;
- Linha 14: Como exercício, permitiremos apenas a navegação circular [index --> página1 --> página2 --> index];
- linhas 15–21: percorremos a matriz para determinar a ordem de navegação desejada;
- linha 16: se verificarmos que routes[i] foi a última página visitada, então a seguinte deve ser routes[i+1];
- linhas 18–19: se não for esse o caso, redirecionamos a aplicação para routes[i], ou seja, não mudamos de página: rejeitamos a navegação;
12.3. Execução
Executamos 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',
// Doc: 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) {}
},
// source code directory
srcDir: 'nuxt-09',
router: {
base: '/nuxt-09/',
middleware: ['client-routing']
},
// server
server: {
port: 81, // default: 3000
host: 'localhost' // default: localhost
}
}
Verifique o seguinte:
- quando estiver na página [Página inicial], só pode navegar para a página [Página 1];
- quando estiver na página [Página 1], só pode navegar para a página [Página 2];
- quando estiver na página [Página 2], só pode navegar para a página [Página inicial];
- Quando solicita um URL inválido, como [http://localhost:81/nuxt-09b/abcd], obtém uma mensagem a indicar que a página solicitada não existe;