Versiones comparadas

Clave

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

...

Debemos importarlo en nuestro main.js:

Bloque de código
languagejs
import router from './router';

Y también en la parte del new Vue:

Bloque de código
languagejs
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:

Bloque de código
languagejs
{
  path: '/frameworkFundeweb'
  name: 'framework fundeweb'
  component: FrameworkFundeweb
}

Aquí nos definimos la ruta que tendremos en la url, un nombre que incluiremos opcionalmento, 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:

Bloque de código
languagejs
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
  }
]
 
const router = new VueRouter({
  mode: 'history',
  routes
})
 
export default router

A los componentes a los que pueden acceder las rutas también se les pueden pasar propiedades, añadiendo un objeto props: {} a la ruta.

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:

Bloque de código
languagexml
<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 con href, pero es mejor utilizar router-link:

Bloque de código
languagexml
<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 con this.$router.pusth():

Bloque de código
languagejs
// 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:

...

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:

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

Los parámetros de esta función son:

...

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

Bloque de código
languagejs
// 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:

Bloque de código
languagejs
// 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 interceptores afterEach que se ejecutarán después de confirmar la navegación. Se definen como los beforeEach, pero sin un parámetro next, pues ya se ha confirmado la navegación:

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

Interceptores por ruta

Se pueden definir interceptores beforeEnter directamente 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:

  • 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.


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.
}