Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.

Tabla de contenidos

...

Importación

Para la navegación en Vue utilizamos el paquete vue-router. Podemos ver la documentación oficial con todos los detalles aquí.

...

Bloque de código
languagejs
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

Definir rutas

Para definir las rutas, tendremos un directorio router/ dentro de src/, que contendrá index.js. En él podemos definir una lista con un objeto por cada ruta, de la siguiente forma:

...

Bloque de código
languagejs
this.$router.push({ name: 'user', params: { userId: '123' } }) 

Definir sub-rutas

Podemos definir rutas hijas de una ruta ya existente, añadiéndolas al parámetro children de la ruta padre:

...

En este ejemplo la ruta padre sería /about, y la ruta hija /about/detalle. A la hora de definir rutas hijas, es importante tener en cuenta que el path no debe incluir la barra ("/"), pues si lo hace lo toma como lo que hay inmediatamente después de la url de nuestro sitio.

Añadir rutas dinámicamente

Podemos añadir rutas en tiempo de ejecución, con la instrucción addRoute que nos proporciona el propio router. Para ello, en archivos JavaScript tendremos que importar el router, y si es desde nuestros componentes podemos acceder directamente a través de this.$router. La función addRoute tiene un primer parámetro opcional en el que le debemos indicar el nombre de la ruta padre si queremos que sea una sub-ruta, y el otro parámetro será el objeto de la ruta:

...

Un detalle a tener en cuenta es que si redirigimos a un sitio externo, las rutas añadidas dinámicamente no son persistentes, cuando volvamos esas rutas no existirán, habría que añadirlas de nuevo.

Vista del router

El router habrá que incluirlo como un componente más. Así, podemos definir la parte de la pantalla que cambiará cuando se cambie de ruta, pudiendo dejar fijo, por ejemplo, un menú lateral, y que sólo se tenga que cargar el contenido de la página.

...

Así, esta parte de la página se sustituirá por el componente correspondiente, cambiando sólo la parte necesaria de la página sin tener que volver a cargarlo todo.

Navegar

Para realizar la navegación, podríamos hacerlo con href, pero es mejor utilizar router-link:

...

Es importante saber que estos valores se reciben como un string.

Interceptores de navegación

Vue router ofrece la posibilidad de añadir código para ejecutarlo cuando se produzca la navegación, con los navigation guards. Son una serie de métodos que podemos definir. El proceso de navegación, y el momento en el que se ejecuta cada método es el siguiente:

...

Estos métodos pueden ser globales o locales a cada ruta.

Interceptores globales

beforeEach

Podemos registrar interceptores de manera global para definir un comportamiento que se ejecute justo antes de producirse la navegación a cualquier ruta. Esto lo hacemos con router.beforeEach, de esta manera:

...

Los interceptores nos pueden venir bien para comprobar algún estado global de la aplicación, como la autorización del usuario.

beforeResolve

Se pueden registrar estos interceptores con router.beforeResolve, de la misma forma que los beforeEach. La diferencia es que estos se ejecutan justo antes de que se confirme la navegación, después de haber ejecutado los interceptores de ruta y de componentes, y que los componentes de ruta asíncronos se resuelvan.

afterEach

También se pueden registrar globalmente interceptoresafterEachque se ejecutarán después de confirmar la navegación. Se definen como losbeforeEach, pero sin un parámetronext, pues ya se ha confirmado la navegación:

Bloque de código
languagejs
router.afterEach((to, from) => {
	// ...
})

Interceptores por ruta

Se pueden definir interceptoresbeforeEnterdirectamente en el objeto que define las rutas, con la misma notación que los interceptores globales before:

Bloque de código
languagejs
{
    path: '/foo',
    component: Foo,
    beforeEnter: (to, from, next) => {
    // ...
}

Interceptores por componente

Se pueden definir interceptores de navegación dentro de los componentes que se pasan a las rutas, con las siguientes opciones:

...

Bloque de código
languagejs
beforeRouteEnter (to, from, next) {
    // called before the route that renders this component is confirmed.
    // does NOT have access to `this` component instance,
    // because it has not been created yet when this guard is called!
},
beforeRouteUpdate (to, from, next) {
    // called when the route that renders this component has changed.
    // This component being reused (by using an explicit `key`) in the new route or not doesn't change anything.
    // For example, for a route with dynamic params `/foo/:id`, when we
    // navigate between `/foo/1` and `/foo/2`, the same `Foo` component instance
    // will be reused (unless you provided a `key` to `<router-view>`), and this hook will be called when that happens.
    // has access to `this` component instance.
},
beforeRouteLeave (to, from, next) {
    // called when the route that renders this component is about to
    // be navigated away from.
    // has access to `this` component instance.
}

Volver arriba tras navegar

Por defecto, al navegar a otra ruta, se mantiene el scroll que teníamos en la ruta anterior. Si queremos que al hacerlo la página se ponga de nuevo al inicio, arriba del todo, tenemos que definir así el scrollBehavior al crear la instancia del router:

...

Podemos consultar la documentación oficial para más detalles acerca del scrollBehavior.

Cacheo de assets

Para que se puedan hacer despliegues correctamente en Kubernetes, Cuando se cambia el nombre a un chunk de webpack, bien por hash bien porque se le cambia manualmente el nombre, si el usuario tiene cacheados según qué ficheros (o el HTML que lo llama o bien el JS) le dará la llamada un 404 si no se siguen dos pasos en el proyecto:

El primero, a nivel de nginx / apache / servidor que despliegue los assets: Evitar el cacheo de los servicios que devuelvan como tipo text/html. Para que el usuario no cachee el documento que realiza las llamadas a los JS/CSS. Como son aplicaciones SPA, los html son pequeños y no afecta excesivamente al rendimiento para el beneficio que da.

El segundo, a nivel de Vue Router, reiniciando la aplicación si se da un 404 en la carga de un chunk. Se ha añadido este código al router para gestionar el error:

Bloque de código
languagejs
router.onError((error) => {
  const hasBeenReloaded = localStorage.getItem('reloadChunkError') === 'on' || false;
  const hasError = /loading chunk \d* failed./i.test(error.message);
  if (hasError && !hasBeenReloaded) {
    localStorage.setItem('reloadChunkError', 'on');
    window.location.reload();
  } else if (hasError) {
    // eslint-disable-next-line no-alert
    alert('No tienes la última versión de la aplicación. Por favor, recarga la aplicación');
  }
});

...