Estás viendo una versión antigua de esta página. Ve a la versión actual.

Comparar con el actual Ver el historial de la página

« Anterior Versión 5 Siguiente »

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

Debemos importarlo en nuestro main.js:

import router from './router';

Y también en la parte delnew Vue:

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

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:

{
  path: '/frameworkFundeweb'
  name: 'framework fundeweb'
  component: FrameworkFundeweb
}

Aquí nos definimos la ruta que tendremos en la url, un nombre que incluiremos opcionalmente, para referenciarlo desde otras partes del código en lugar de escribir la ruta, y por último el componente que se mostrará cuando naveguemos a la ruta.

Un ejemplo de fichero completo sería este:

import Vue from 'vue'
import VueRouter from  'vue-router'
import Home from '../views/Home.vue'
import Profile from '../views/Profile.vue'
 
Vue.use(VueRouter);
 
const routes = [
  {
    path: "/",
    name: "home",
    component: Home
  },
  {
    path: '/profile',
    name: 'profile',
    component: Profile,
    props: true
  }
]
 
const router = new VueRouter({
  mode: 'history',
  routes
})
 
export default router

Si nos fijamos, podemos poner en cada ruta un campo props a true. Con esto, cuando naveguemos a esa ruta, los parámetros que se le pasen cuyo nombre coincida con un prop definido en el componente se asignará a este directamente. Es importante tener en cuenta que para hacer esto, tendremos que hacer la navegación utilizando el name, y no el path, pues si no no funciona.

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.

Para esto, en el archivo .vue inicial, el que se carga al principio, basta con incluir:

<router-view></router-view>

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.

Para relizar la navegación, podríamos hacerlo conhref, pero es mejor utilizar router-link:

<router-link :to="{ name: 'nuevaComunicacion', params: { idReenviar: fila.data.id }}">

Como vemos, se le indica a dónde navegar con el nombre que hemos definido previamente para la ruta. Además podemos pasar datos como parámetro, con params. Después, en el componente al que se navega, podemos coger dichos datos referenciando a this.$route.params. En este ejemplo, el objeto que se ha pasado se cogería con this.$route.params.idReenviar.

Si queremos hacerlo de forma programática, en la parte de JavaScript conthis.$router.pusth():

// path
this.$router.push('home')
 
// path
this.$router.push({ path: 'home' })
 
// nombre + parámetros
this.$router.push({ name: 'user', params: { userId: '123' } })

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:

  1. La navegación es activada.

  2. Se llama a todos los beforeRouterLeave que se hayan registrado y que no van a ser reutilizados en la siguiente ruta a la que voy.

  3. Se llama a todos los interceptores globales beforeEach.

  4. Se llama a todos los beforeRouteUpdate de los componentes que van a ser reutilizados en la siguiente ruta a la que voy.

  5. Se llama a beforeEnter que hemos configurado en la ruta a la que voy.

  6. Se resuelven toda la asincronía de componentes de esa ruta.

  7. Se llama a beforeRouteEnter de los componentes que van a estar activos.

  8. Se llama a los interceptores globales beforeResolve.

  9. Se da la navegación como confirmada.

  10. Se llama al interceptor afterEach.

  11. Se llama a los callbacks pasados a next in beforeRouteEnter.

  12. Y vuelta a empezar cuando se lanza una nueva navegación.

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 conrouter.beforeEach, de esta manera:

router.beforeEach((to, from, next) => {
	// ...
})

Los parámetros de esta función son:

  • to: objeto con la información de la ruta a la que se navega.

  • from: objeto con la información de la ruta desde la que se navega.

  • next: es una función que permite reanudar la navegación. Nos permite llamarla de diferentes maneras para tener diferentes comportamientos: next() reanuda la navegación hacia la ruta indicada en to. next('/') redirige a la ruta que se le pase como parámetro. next(false) aborta la navegación. next(new Error()) aborta la navegación y se ejecuta el callback onError.

Hay que asegurarse de que sólo se llama anext()una vez, en caso contrario podemos encontrarnos errores. Por ejemplo, esto estaría mal:

// BAD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  // if the user is not authenticated, `next` is called twice
  next()
})

La forma correcta sería esta:

// GOOD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  else next()
})

Se pueden registrar múltiples interceptores del mismo tipo, y estos se ejecutarán en orden de aparición, es decir, el primero en registrarse es el primero que se ejecuta.

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:

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:

{
    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:

  • beforeRouteEnter: se llama antes de que la ruta que navega a este componente se confirme. No tiene acceso al this del componente, pues todavía no se ha creado.

  • beforeRouteUpdate: se llama antes de que la ruta que lleva a este componente haya cambiado. Por ejemplo, para una ruta con parámetros dinámicos /foo/:id, cuando navegamos entre /foo/1 y /foo/2, se reutiliza el mismo componente, y este interceptor se ejecuta cuando eso ocurre. Éste sí tiene acceso a this.

  • beforeRouteLeave: se ejecuta cuando la ruta que renderiza este componente va a navegar a otra ruta. También tiene acceso a this.


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:

const router = new VueRouter({
  ...,
  scrollBehavior (to, from, savedPosition) {
    return { x: 0, y: 0 };
  }
})

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

  • Sin etiquetas