Skip to content

Emparejamiento de Rutas Dinámicas con Parámetros

Con frecuencia necesitaremos asignar rutas con el patrón establecido al mismo componente. Por ejemplo, podemos tener un componente User que debe ser renderizado para todos los usuarios pero con diferentes IDs de usuario. En Vue Router podemos usar un segmento dinámico en la ruta para conseguirlo, lo llamamos un parámetro:

js
import User from './User.vue'

// esto es pasado a `createRouter`
const routes = [
  // los segmentos dinámicos comienzan con dos puntos
  { path: '/users/:id', component: User },
]

Ahora las URLs como /users/johnny y /users/jolyne se asignarán a la misma ruta.

Un parámetro se indica con dos puntos :. Cuando se encuentra una ruta, el valor de sus parámetros se muestra como route.params en cada componente. Por lo tanto, podemos mostrar el ID del usuario actual actualizando la plantilla User a esto:

vue
<template>
  <div>
    <!-- La ruta actual es accesible como $route en el template -->
    User {{ $route.params.id }}
  </div>
</template>

Puedes tener múltiples parámetros en la misma ruta, y se asignarán a los campos correspondientes en route.params. Por ejemplo:

modeloruta coincidenteroute.params
/users/:username/users/eduardo{ username: 'eduardo' }
/users/:username/posts/:postId/users/eduardo/posts/123{ username: 'eduardo', postId: '123' }

Además de route.params, el objeto route también expone otra información útil como route.query (si hay una consulta en la URL), route.hash, etc. Puedes consultar todos los detalles en la Referencia de la API.

Se puede encontrar una demostración funcional de este ejemplo aquí.

Reaccionar a los Cambios de Parámetros

Una cosa a tener en cuenta cuando se utilizan rutas con parámetros es que cuando el usuario navega desde /users/johnny a /users/jolyne, se reutilizará la misma instancia del componente. Dado que ambas rutas renderizan el mismo componente, esto es más eficiente que destruir la instancia antigua y crear una nueva. Sin embargo, esto también significa que los hooks del ciclo de vida del componente no serán llamados.

Para reaccionar a los cambios de parámetros en el mismo componente, puedes simplemente observar cualquier cosa en el objeto route, en este escenario, el route.params:

vue
<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()

watch(
  () => route.params.id,
  (newId, oldId) => {
    // reaccionar a los cambios de ruta...
  }
)
</script>
vue
<script>
export default {
  created() {
    this.$watch(
      () => this.$route.params.id,
      (newId, oldId) => {
        // reaccionar a los cambios de ruta...
      }
    )
  },
}
</script>

O bien, usa el protector de navegación beforeRouteUpdate, que te permite también cancelar la navegación:

vue
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
// ...

onBeforeRouteUpdate(async (to, from) => {
  // reaccionar a los cambios de ruta...
  userData.value = await fetchUser(to.params.id)
})
</script>
vue
<script>
export default {
  async beforeRouteUpdate(to, from) {
    // reaccionar a los cambios de ruta...
    this.userData = await fetchUser(to.params.id)
  },
  // ...
}
</script>

Catch all / 404 Not found Route

Los parámetros regulares sólo coincidirán con los caracteres entre fragmentos de url, separados por /. Si queremos que coincida con cualquier cosa, podemos utilizar un parámetro personalizado con una expresión regular (regexp) añadiendo el regexp entre paréntesis justo después del parámetro:

js
const routes = [
  // coincidirá con todo y lo pondrá en `route.params.pathMatch`.
  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  // buscará cualquier cosa que empiece por `/user-` y la pondrá en `route.params.afterUser`.
  { path: '/user-:afterUser(.*)', component: UserGeneric },
]

En este caso concreto, estamos utilizando una regexp personalizada entre paréntesis y marcando el parámetro pathMatch como opcionalmente repetible. Esto nos permite navegar directamente a la ruta si lo necesitamos dividiendo el path en un array:

js
router.push({
  name: 'NotFound',
  // conserva la ruta actual y elimina el primer carácter para evitar que la URL de destino empiece por `//`.
  params: { pathMatch: route.path.substring(1).split('/') },
  // preservar la consulta existente y el hash si existe
  query: route.query,
  hash: route.hash,
})

Ve más en la sección parámetros repetidos.

Si estás usando el modo Historial, asegúrate de seguir las instrucciones para configurar correctamente también tu servidor.

Patrones de Emparejamiento Avanzados

Vue Router usa su propia sintaxis de emparejamiento de rutas, inspirada en la que utiliza express, por lo que admite muchos patrones de coincidencia avanzados tales como parámetros opcionales, cero o más / uno o más requisitos e incluso patrones de expresiones regulares personalizados. Por favor, consulta la documentación de Emparejamiento Avanzado para explorarlos.

Publicado bajo licencia MIT.

Build faster with AI
New Masterclass to help you leverage AI in your Vue workflow.
Get Early Access