12. Ejemplo [nuxt-09]: control de la navegación
El ejemplo [nuxt-09] utiliza un middleware para controlar la navegación del cliente. Además, se añade una nueva vista para los casos en los que el usuario solicita al servidor un URL que no existe en la aplicación.
El ejemplo [nuxt-09] se obtiene inicialmente copiando el ejemplo [nuxt-01]:

12.1. La página [_.vue]
Hemos dicho que las rutas de la aplicación se construyen a partir del contenido de la carpeta [pages]. En este caso, hemos añadido a dicha carpeta la página [_.vue]. Esta página en concreto se muestra cada vez que la aplicación redirige a una página que no existe. En nuestro ejemplo, esto no puede ocurrirle al cliente. Pero sí puede ocurrirle al servidor si, por ejemplo, se le solicita la página URL en lugar de la [/nuxt-09/abcd]. Como la página [abcd] no existe, se mostrará la página [_.vue]. En este caso, será la siguiente:

El código de la página [_.vue] es el siguiente:
<!-- definición HTML de la vista -->
<template>
<!-- diseño -->
<Layout :left="true" :right="true">
<!-- alerta en la columna de la derecha -->
<template slot="right">
<!-- mensaje sobre fondo amarillo -->
<b-alert show variant="warning" align="center">
<h4>La page demandée n'existe pas</h4>
</b-alert>
</template>
<!-- menú de navegación en la columna de la izquierda -->
<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 y servidor
console.log('[404 beforeCreate]')
},
created() {
// cliente y servidor
console.log('[404 created]')
},
beforeMount() {
// solo cliente
console.log('[404 beforeMount]')
},
mounted() {
// solo cliente
console.log('[404 mounted]')
}
}
</script>
12.2. El middleware del cliente
El código del middleware del cliente [client-routing] es el siguiente:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function({ route, from, redirect }) {
// solo cliente
if (process.client) {
console.log('[client-routing]')
// orden de navegación deseado
const routes = ['index', 'page1', 'page2', 'index']
// ruta actual
const current = route.name
// ruta anterior
const previous = from.name
// se desea una navegación circular
// rutas[i] a rutas[i+1]
for (let i = 0; i < routes.length - 1; i++) {
if (previous === routes[i] && current !== routes[i + 1]) {
// nos quedamos en la misma página
redirect({ name: routes[i] })
return
}
}
}
}
- línea 3: sabemos que la función de enrutamiento solo recibe un parámetro, el objeto [context] de quien la ejecuta, ya sea el servidor o el cliente. La notación [function({ route, from, redirect })]
- es equivalente a [function({ route:route, from:from, redirect:redirect })];
- lo que da como resultado { route:route, from:from, redirect:redirect } <-- contexto;
- lo que crea tres parámetros [route, from, redirect] tales como:
- route=context.route;
- redirect=context.redirect;
- from=context.from;
La documentación de [nuxt] utiliza ampliamente esta notación. Es necesario conocerla;
- línea 8: una tabla con los nombres de las páginas en el orden de navegación deseado
- línea 10: el nombre de la página de destino de la ruta actual;
- línea 12: el nombre de la página anterior de la ruta actual;
- línea 14: a modo de ejercicio, solo se permitirá una navegación circular [index --> page1 --> page2 --> index];
- líneas 15-21: recorremos la tabla siguiendo el orden de navegación deseado;
- línea 16: si se descubre que routes[i] fue la última página enrutada, entonces la siguiente debe ser routes[i+1];
- líneas 18-19: si no es así, se redirige la aplicación a «routes[i]», es decir, no se cambia de página: se rechaza la navegación;
12.3. Exécution
Ejecutamos el ejemplo con el siguiente archivo [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) {}
},
// directorio del código fuente
srcDir: 'nuxt-09',
router: {
base: '/nuxt-09/',
middleware: ['client-routing']
},
// servidor
server: {
port: 81, // por defecto: 3000
host: 'localhost' // por defecto: localhost
}
}
Comprueba los siguientes puntos:
- cuando se encuentre en la página [Home], solo podrá navegar hacia la página [Page 1];
- cuando se encuentre en la página [Page 1], solo podrá navegar a la página [Page 2];
- cuando se encuentre en la página [Page 2], solo podrá navegar a la página [Home];
- cuando solicitas una URL incorrecta, como [http://localhost:81/nuxt-09b/abcd], obtienes la pantalla que indica que la página solicitada no existe;