El enrutador Vue

Cómo usar el enrutador Vue, una de las piezas esenciales de una aplicación Vue

Introducción

En una aplicación web de JavaScript, un enrutador es la parte que sincroniza la vista que se muestra actualmente con el contenido de la barra de direcciones del navegador.

En otras palabras, es la parte que hace que la URL cambie cuando haces clic en algo en la página y ayuda a mostrar la vista correcta cuando accedes a una URL específica.

Tradicionalmente, la Web se basa en URL. Cuando accedes a una determinada URL, se muestra una página específica.

Con la introducción de aplicaciones que se ejecutan dentro del navegador y cambian lo que ve el usuario, muchas aplicaciones rompieron esta interacción y tuvo que actualizar manualmente la URL con la API de historial del navegador.

Necesita un enrutador cuando necesita sincronizar URL con vistas en su aplicación. Es una necesidad muy común, y todos los marcos modernos más importantes ahora le permiten administrar el enrutamiento.

La biblioteca Vue Router es el camino a seguir para las aplicaciones Vue.js. Vue no impone el uso de esta biblioteca. Puede usar cualquier biblioteca de enrutamiento genérica que desee, o también crear su propia integración de API de historial, pero el beneficio de usar Vue Router es que esoficial.

Esto significa que lo mantienen las mismas personas que mantienen Vue, por lo que obtienes una integración más consistente en el marco y la garantía de que siempre será compatible en el futuro, pase lo que pase.

Instalación

Vue Router está disponible a través denpmcon el paquete llamadovue-router.

Si usa Vue a través de una etiqueta de script, puede incluir Vue Router usando

<script src="https://unpkg.com/vue-router"></script>

unpkg.com es una herramienta muy útil que hace que todos los paquetes npm estén disponibles en el navegador con un simple enlace

Si usa elVue CLI, instálelo usando

npm install vue-router

Una vez que instalasvue-routery ponerlo a disposición mediante una etiqueta de secuencia de comandos o mediante Vue CLI, ahora puede importarlo en su aplicación.

Lo importas despuésvuey tu llamasVue.use(VueRouter)aInstalar en pcdentro de la aplicación:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

Después de llamarVue.use()pasando el objeto del enrutador, en cualquier componente de la aplicación tienes acceso a estos objetos:

  • this.$routeres el objeto del enrutador
  • this.$routees el objeto de ruta actual

El objeto enrutador

El objeto de enrutador, al que se accede mediantethis.$routerdesde cualquier componente cuando el Vue Router está instalado en el componente raíz de Vue, ofrece muchas características interesantes.

Podemos hacer que la aplicación navegue a una nueva ruta usando

  • this.$router.push()
  • this.$router.replace()
  • this.$router.go()

que se asemejan alpushState,replaceStateygométodos de la API de historial.

push()se usa para ir a una nueva ruta, agregando un nuevo elemento al historial del navegador.replace()es lo mismo, excepto que no empuja un nuevo estado a la historia.

Muestras de uso:

this.$router.push('about') //named route, see later
this.$router.push({ path: 'about' })
this.$router.push({ path: 'post', query: { post_slug: 'hello-world' } }) //using query parameters (post?post_slug=hello-world)
this.$router.replace({ path: 'about' })

go()va de un lado a otro, aceptando un número que puede ser positivo o negativo para retroceder en la historia:

this.$router.go(-1) //go back 1 step
this.$router.go(1) //go forward 1 step

Definiendo las rutas

Estoy usando unComponente de archivo único de Vueen este ejemplo.

En la plantilla utilizo unnav tag that has 3 router-linkcomponentes, que tienen una etiqueta (Inicio / Inicio de sesión / Acerca de) y una URL asignada a través deltoatributo.

losrouter-viewEl componente es donde el enrutador Vue colocará el contenido que coincida con la URL actual.

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link>
      <router-link to="/login">Login</router-link>
      <router-link to="/about">About</router-link>
    </nav>
    <router-view></router-view>
  </div>
</template>

Arouter-linkcomponente hace unaetiqueta de forma predeterminada (puede cambiar eso). Cada vez que cambia la ruta, ya sea haciendo clic en un enlace o cambiando la URL, unrouter-link-activeLa clase se agrega al elemento que se refiere a la ruta activa, lo que le permite darle estilo.

In the JavaScript part we first include and install the router, then we define 3 componentes de ruta.

Los pasamos a la inicialización delrouterobject, y pasamos este objeto a la instancia raíz de Vue.

Aquí está el código:

<script>
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const Home = { template: ‘<div>Home</div>’ }

const Login = { template: ‘<div>Login</div>’ }

const About = { template: ‘<div>About</div>’ }

const router = new VueRouter({ routes: [ { path: ‘/’, component: Home }, { path: ‘/login’, component: Login }, { path: ‘/about’, component: About } ] })

new Vue({ router }).$mount(’#app’) </script>

Por lo general, en una aplicación Vue, crea una instancia y monta la aplicación raíz usando:

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

Cuando usa el enrutador Vue, no pasa unrenderpropiedad, pero en su lugar, usarouter.

La sintaxis utilizada en el ejemplo anterior:

new Vue({
  router
}).$mount('#app')

es una abreviatura de

new Vue({
  router: router
}).$mount('#app')

Vea en el ejemplo, pasamos unroutesmatriz a laVueRouterconstructor. Cada ruta en esta matriz tiene unpathycomponentparams.

Si pasa unnameparam también, tienes unruta nombrada.

Uso de rutas con nombre para pasar parámetros a los métodos de inserción y reemplazo del enrutador

¿Recuerda cómo usamos el objeto Router para impulsar un nuevo estado antes?

this.$router.push({ path: 'about' })

Con una ruta nombrada podemos pasar parámetros a la nueva ruta:

this.$router.push({ name: 'post', params: { post_slug: 'hello-world' } })

Lo mismo va parareplace():

this.$router.replace({ name: 'post', params: { post_slug: 'hello-world' } })

La aplicación renderizará el componente de ruta que coincide con la URL pasada al enlace.

Se crea una instancia del nuevo componente de ruta que maneja la URL y se llama a sus guardias, y se destruirá el antiguo componente de ruta.

Guardias de ruta

Como mencionamosguardias, vamos a presentarlos.

Puede pensar en ellos como enlaces de ciclo de vida o middleware, que son funciones llamadas en momentos específicos durante la ejecución de la aplicación. Puede saltar y alterar la ejecución de una ruta, redireccionando o cancelando la solicitud.

Puede tener guardias globales agregando una devolución de llamada albeforeEach()yafterEach()propiedad del enrutador.

  • beforeEach()se llama antes de que se confirme la navegación
  • beforeResolve()se llama cuando beforeEach se ejecuta y todos los componentesbeforeRouterEnterybeforeRouteUpdateSe llama a los guardias, pero antes de que se confirme la navegación. El cheque final, si quieres
  • afterEach()se llama después de que se confirma la navegación

¿Qué significa “la navegación está confirmada”? Lo veremos en un segundo. Mientras tanto, piense en ello como "la aplicación puede ir a esa ruta".

El uso es:

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

toyfromrepresentan los objetos de ruta hacia y desde donde vamos.beforeEachtiene un parámetro adicionalnextque si llamamos confalsecomo parámetro, bloqueará la navegación y hará que no se confirme. Al igual que en el middleware de Node, si está familiarizado, siempre se debe llamar a next (); de lo contrario, la ejecución se bloqueará.

Los componentes de ruta única también tienen protecciones:

  • beforeRouteEnter(from, to, next)se llama antes de que se confirme la ruta actual
  • beforeRouteUpdate(from, to, next)se llama cuando la ruta cambia pero el componente que la administra sigue siendo el mismo (con enrutamiento dinámico, ver a continuación)
  • beforeRouteLeave(from, to, next)se llama cuando nos alejamos de aquí

Mencionamos la navegación. Para determinar si se confirma la navegación a una ruta, Vue Router realiza algunas verificaciones:

  • llamabeforeRouteLeaveguardia en los componentes actuales
  • llama al enrutadorbeforeEach()Guardia
  • llama albeforeRouteUpdate()en cualquier componente que necesite ser reutilizado, si existe
  • llama albeforeEnter()guardia en el objeto de ruta (no lo mencioné, pero puedes miraraquí)
  • llama albeforeRouterEnter()en el componente que debemos ingresar
  • llama al enrutadorbeforeResolve()Guardia
  • si todo estuvo bien, ¡la navegación está confirmada!
  • llama al enrutadorafterEach()Guardia

Puede utilizar los guardias específicos de la ruta (beforeRouteEnterybeforeRouteUpdateen caso de enrutamiento dinámico) como ganchos de ciclo de vida, para que pueda comenzarsolicitudes de obtención de datospor ejemplo.

Enrutamiento dinámico

El ejemplo anterior muestra una vista diferente basada en la URL, manejando el/,/loginy/aboutrutas.

Una necesidad muy común es manejar rutas dinámicas, como tener todas las publicaciones debajo/post/, cada uno con el nombre de la babosa:

  • /post/first
  • /post/another-post
  • /post/hello-world

Puede lograr esto utilizando un segmento dinámico.

Esos eran segmentos estáticos:

const router = new VueRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/login', component: Login },
    { path: '/about', component: About }
  ]
})

agregamos un segmento dinámico para manejar publicaciones de blog:

const router = new VueRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/post/:post_slug', component: Post },
    { path: '/login', component: Login },
    { path: '/about', component: About }
  ]
})

Observe la:post_slugsintaxis. Esto significa que puede usar cualquier cadena y que se asignará a lapost_slugmarcador de posición.

No está limitado a este tipo de sintaxis. Vue confía enesta bibliotecapara analizar rutas dinámicas, y puede volverse loco conExpresiones regulares.

Ahora, dentro del componente Publicar ruta, podemos hacer referencia a la ruta usando$route, y el post slug usando$route.params.post_slug:

const Post = {
  template: '<div>Post: {{ $route.params.post_slug }}</div>'
}

Podemos usar este parámetro para cargar el contenido desde el backend.

Puede tener tantos segmentos dinámicos como desee, en la misma URL:

/post/:author/:post_slug

¿Recuerdas cuando antes hablamos sobre lo que sucede cuando un usuario navega a una nueva ruta?

En el caso de las rutas dinámicas, lo que sucede es un poco diferente.

Para ser más eficiente en lugar de destruir el componente de ruta actual y volver a instanciarlo, reutiliza la instancia actual.

Cuando esto sucede, Vue llama albeforeRouteUpdateevento del ciclo de vida. Allí podrás realizar cualquier operación que necesites:

const Post = {
  template: '<div>Post: {{ $route.params.post_slug }}</div>'
  beforeRouteUpdate(to, from, next) {
    console.log(`Updating slug from ${from} to ${to}`)
    next() //make sure you always call next()
  }
}

Usando accesorios

En los ejemplos, usé$route.params.*para acceder a los datos de la ruta. Un componente no debe estar tan estrechamente acoplado con el enrutador, y en su lugar, podemos usar accesorios:

const Post = {
  props: ['post_slug'],
  template: '<div>Post: {{ post_slug }}</div>'
}

const router = new VueRouter({ routes: [ { path: ‘/post/:post_slug’, component: Post, props: true } ] })

Observe laprops: truepasado al objeto de ruta para habilitar esta funcionalidad.

Rutas anidadas

Antes mencioné que puede tener tantos segmentos dinámicos como desee, en la misma URL, como:

/post/:author/:post_slug

Entonces, digamos que tenemos un componente Autor que se ocupa del primer segmento dinámico:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script> import Vue from ‘vue’ import VueRouter from ‘vue-router’

Vue.use(VueRouter)

const Author = { template: ‘<div>Author: {{ $route.params.author}}</div>’ }

const router = new VueRouter({ routes: [ { path: ‘/post/:author’, component: Author } ] })

new Vue({ router }).$mount(’#app’) </script>

Podemos insertar un segundorouter-viewinstancia de componente dentro de la plantilla de Autor:

const Author  = {
  template: '<div>Author: {{ $route.params.author}}<router-view></router-view></div>'
}

agregamos el componente Publicar:

const Post = {
  template: '<div>Post: {{ $route.params.post_slug }}</div>'
}

y luego inyectaremos la ruta dinámica interna en la configuración de VueRouter:

const router = new VueRouter({
  routes: [{
    path: '/post/:author',
    component: Author,
    children: [
      path: ':post_slug',
      component: Post
    ]
  }]
})

Descarga mi gratisManual de Vue


Más tutoriales de vue: