Skip to content
← Todas las preguntas
⚡ Intermedio

¿Cómo funciona Vue Router y qué son los navigation guards?

🧭 Vue Router

Vue Router mapea rutas URL a componentes. Cuando la URL cambia, Vue Router renderiza el componente correspondiente sin recargar la página completa. Los navigation guards son hooks que se ejecutan antes, durante o después de cada navegación, permitiéndote controlar el acceso, cancelar navegaciones o ejecutar efectos secundarios.

Configuración básica

ts
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: () => import('./views/Home.vue') },
    {
      path: '/dashboard',
      component: () => import('./views/Dashboard.vue'),
      meta: { requiresAuth: true }
    },
    {
      path: '/:pathMatch(.*)*',
      component: () => import('./views/NotFound.vue')
    }
  ]
})

createWebHistory() usa la History API del navegador para URLs limpias (/dashboard). createWebHashHistory() usa URLs basadas en hash (/#/dashboard) para entornos sin reescritura de URLs en el servidor.

Cada () => import(...) es un import dinámico que crea un chunk JavaScript separado, cargado solo cuando el usuario navega a esa ruta.

Los guards interceptan las navegaciones en tres niveles: global, por ruta y dentro del componente.

Guards globales

Se ejecutan en cada navegación de la app:

ts
router.beforeEach((to, from) => {
  if (to.meta.requiresAuth && !isAuthenticated()) {
    return { path: '/login', query: { redirect: to.fullPath } }
  }
})

Devolver un objeto de ruta redirige. Devolver false cancela la navegación. No devolver nada (o devolver true) la permite.

Guards por ruta

Se ejecutan solo para una ruta específica:

ts
const routes = [
  {
    path: '/admin',
    component: () => import('./views/Admin.vue'),
    beforeEnter: (to, from) => {
      if (!isAdmin()) return { path: '/' }
    }
  }
]

Guards dentro del componente

Se ejecutan dentro del componente al que se navega o del que se sale:

vue
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'

onBeforeRouteLeave((to, from) => {
  if (hasUnsavedChanges.value) {
    return confirm('¿Salir sin guardar?')
  }
})

onBeforeRouteUpdate((to, from) => {
  // mismo componente, diferentes params (ej. /users/1 → /users/2)
  loadUser(to.params.id)
})
</script>
Open in Vue Playground

Orden de ejecución de los guards

Al navegar de /a a /b:

Diagrama del orden de ejecución de los navigation guards de Vue Router
  1. onBeforeRouteLeave en el componente que se abandona
  2. router.beforeEach (global)
  3. beforeEnter en la ruta destino (por ruta)
  4. onBeforeRouteUpdate si se reutiliza un componente
  5. router.beforeResolve (global, después de resolver componentes asíncronos)
  6. Navegación confirmada
  7. router.afterEach (global, no se puede cancelar)

Route meta

Adjunta datos arbitrarios a las rutas mediante meta. Los guards y componentes pueden leerlos:

ts
const routes = [
  {
    path: '/settings',
    component: () => import('./views/Settings.vue'),
    meta: { requiresAuth: true, title: 'Settings' }
  }
]

router.afterEach((to) => {
  document.title = (to.meta.title as string) ?? 'My App'
})

Patrones comunes

NecesidadGuardDónde
Proteger rutas autenticadasbeforeEachGlobal
Evitar salir de formularios sin guardaronBeforeRouteLeaveEn el componente
Redirigir URLs antiguasbeforeEnterPor ruta
Analytics/seguimiento de páginaafterEachGlobal
Establecer título de páginaafterEachGlobal
Esperar datos asíncronos antes de mostrar la páginabeforeResolveGlobal

Ver también: ¿Cómo implementar autenticación con Vue Router? · ¿Cómo funciona el routing basado en archivos en Nuxt? · ¿Cómo implementar lazy loading?

Referencias

Publicado bajo la licencia MIT.