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'
}
})