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

12.1. A página [_.vue]
Já mencionamos que as rotas do aplicativo são construídas a partir do conteúdo da pasta [pages]. Aqui, adicionamos a essa pasta a página [_.vue]. Essa página específica é exibida sempre que o aplicativo é redirecionado para uma página que não existe. No nosso exemplo aqui, isso não pode acontecer para o cliente. Mas pode acontecer para o servidor se, por exemplo, for solicitada a página URL [/nuxt-09/abcd]. Como a página [abcd] não existe, será exibida a página [_.vue]. Neste caso, será a seguinte:

O código da página [_.vue] é o seguinte:
<!-- definição HTML da visualização -->
<template>
<!-- formatação -->
<Layout :left="true" :right="true">
<!-- alerta na coluna da direita -->
<template slot="right">
<!-- mensagem em 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() {
// somente cliente
console.log('[404 beforeMount]')
},
mounted() {
// somente 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 }) {
// somente cliente
if (process.client) {
console.log('[client-routing]')
// ordem de navegação desejada
const routes = ['index', 'page1', 'page2', 'index']
// rota atual
const current = route.name
// rota anterior
const previous = from.name
// deseja-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 roteamento recebe apenas um parâmetro, o objeto [context] daquele que a executa, seja servidor ou 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 essa notação. É preciso conhecê-la;
- linha 8: uma tabela com os nomes das páginas na ordem de navegação desejada
- linha 10: o nome da página de destino do roteamento atual;
- linha 12: o nome da página anterior do roteamento 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 desejada;
- linha 16: se for constatado que routes[i] foi a última página roteada, então a próxima deve ser routes[i+1];
- linhas 18-19: se não for esse o caso, redireciona-se o aplicativo para routes[i], ou seja, não se muda de página: a navegação é recusada;
12.3. Exécution
Executamos o exemplo com o seguinte arquivo [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 você estiver na página [Home], só poderá navegar para a página [Page 1];
- quando você estiver na página [Page 1], só poderá navegar para a página [Page 2];
- quando você estiver na página [Page 2], só poderá navegar para a página [Home];
- quando você solicita uma URL incorreta, como [http://localhost:81/nuxt-09b/abcd], você obtém a tela que indica que a página solicitada não existe;