Vue Router Advanced

Master routing techniques for complex Vue applications

🧭 Advanced Vue Router

Vue Router provides powerful features for complex navigation including nested routes, navigation guards, lazy loading, and dynamic routing. Master these techniques to build sophisticated single-page applications.


// Advanced router configuration
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/dashboard',
      component: Dashboard,
      meta: { requiresAuth: true }
    }
  ]
})
                                    

Advanced Router Features

🔒

Navigation Guards

Control route access

router.beforeEach((to, from) => {
  if (to.meta.requiresAuth) {
    return '/login'
  }
})
🌳

Nested Routes

Parent-child routing

children: [
  { path: 'profile', 
    component: Profile },
  { path: 'settings', 
    component: Settings }
]
âš¡

Lazy Loading

Load routes on demand

component: () => 
  import('./views/About.vue')
🎯

Dynamic Routes

Routes with parameters

path: '/user/:id',
component: UserProfile

🔹 Navigation Guards

Protect routes and control navigation flow:

// router/index.js
import { createRouter } from 'vue-router'

const router = createRouter({
  routes: [
    {
      path: '/admin',
      component: Admin,
      meta: { requiresAuth: true, role: 'admin' }
    }
  ]
})

// Global guard
router.beforeEach(async (to, from) => {
  const isAuthenticated = checkAuth()
  
  if (to.meta.requiresAuth && !isAuthenticated) {
    return { name: 'Login' }
  }
  
  if (to.meta.role === 'admin' && !isAdmin()) {
    return { name: 'Forbidden' }
  }
})

// Per-route guard
const routes = [{
  path: '/users/:id',
  component: UserProfile,
  beforeEnter: (to, from) => {
    // Validate user ID
    if (!isValidId(to.params.id)) {
      return false
    }
  }
}]

🔹 Nested Routes

Create complex layouts with parent-child relationships:

// router/index.js
const routes = [
  {
    path: '/dashboard',
    component: DashboardLayout,
    children: [
      {
        path: '',
        name: 'DashboardHome',
        component: DashboardHome
      },
      {
        path: 'profile',
        name: 'Profile',
        component: UserProfile
      },
      {
        path: 'settings',
        name: 'Settings',
        component: Settings,
        children: [
          { path: 'account', component: AccountSettings },
          { path: 'privacy', component: PrivacySettings }
        ]
      }
    ]
  }
]
<!-- DashboardLayout.vue -->
<template>
  <div class="dashboard">
    <Sidebar />
    <main>
      <!-- Nested routes render here -->
      <RouterView />
    </main>
  </div>
</template>

🔹 Lazy Loading Routes

Improve performance by loading routes on demand:

// router/index.js
const routes = [
  {
    path: '/',
    component: Home // Loaded immediately
  },
  {
    path: '/about',
    // Lazy loaded when route is visited
    component: () => import('@/views/About.vue')
  },
  {
    path: '/products',
    component: () => import('@/views/Products.vue'),
    children: [
      {
        path: ':id',
        // Nested lazy loading
        component: () => import('@/views/ProductDetail.vue')
      }
    ]
  }
]

// Group components into chunks
const routes = [
  {
    path: '/admin',
    component: () => import(
      /* webpackChunkName: "admin" */
      '@/views/Admin.vue'
    )
  }
]

🔹 Dynamic Route Matching

Handle dynamic segments and parameters:

// router/index.js
const routes = [
  {
    path: '/user/:id',
    component: User,
    props: true // Pass params as props
  },
  {
    path: '/post/:id(\\d+)', // Regex: only numbers
    component: Post
  },
  {
    path: '/files/:path(.*)', // Match everything
    component: FileViewer
  }
]
<!-- User.vue -->
<script setup>
import { useRoute } from 'vue-router'

// Access route params
const route = useRoute()
console.log(route.params.id)

// Or receive as props
defineProps(['id'])
</script>

<template>
  <div>User ID: {{ $route.params.id }}</div>
</template>

🔹 Programmatic Navigation

Navigate using JavaScript instead of router-link:

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

const router = useRouter()

// Navigate to route
function goToUser(id) {
  router.push(`/user/${id}`)
}

// Navigate with name
function goToProfile() {
  router.push({ name: 'Profile', params: { id: 123 } })
}

// Navigate with query
function search(term) {
  router.push({ path: '/search', query: { q: term } })
}

// Replace current route (no history)
function replaceRoute() {
  router.replace('/new-page')
}

// Go back/forward
function goBack() {
  router.go(-1) // or router.back()
}
</script>

🔹 Route Meta Fields

Attach custom data to routes:

const routes = [
  {
    path: '/admin',
    component: Admin,
    meta: {
      requiresAuth: true,
      role: 'admin',
      title: 'Admin Panel',
      layout: 'AdminLayout'
    }
  }
]

// Use in navigation guard
router.beforeEach((to, from) => {
  // Set page title
  document.title = to.meta.title || 'Default Title'
  
  // Check authentication
  if (to.meta.requiresAuth && !isLoggedIn()) {
    return '/login'
  }
})

🧠 Test Your Knowledge

Which guard runs before every route navigation?