Vue Router is the official router for Vue.js, enabling you to build single-page applications with multiple views and navigation.
Installation
bash
npm install vue-router@4Basic Setup
javascript
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'
const routes = [
{ path: '/', name: 'Home', component: Home },
{ path: '/about', name: 'About', component: About }
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')Route Configuration
Dynamic Routes
javascript
const routes = [
{
path: '/user/:id',
name: 'User',
component: User,
props: true
},
{
path: '/post/:slug',
name: 'Post',
component: Post,
props: (route) => ({ slug: route.params.slug })
}
]Nested Routes
javascript
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
path: '',
component: UserHome
},
{
path: 'profile',
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
]
}
]Named Routes
javascript
const routes = [
{
path: '/user/:id',
name: 'user',
component: User
}
]
// Navigate using name
router.push({ name: 'user', params: { id: 123 } })Navigation
Programmatic Navigation
javascript
import { useRouter } from 'vue-router'
const router = useRouter()
// Navigate to path
router.push('/home')
// Navigate with object
router.push({ path: '/home' })
router.push({ name: 'Home' })
// Navigate with params
router.push({ name: 'User', params: { id: 123 } })
// Navigate with query
router.push({ path: '/search', query: { q: 'vue' } })
// Replace current route
router.replace('/home')
// Go back/forward
router.go(-1)
router.go(1)RouterLink Component
vue
<template>
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink :to="{ name: 'About' }">About</RouterLink>
<RouterLink :to="`/user/${userId}`">User</RouterLink>
<RouterLink
:to="{ name: 'User', params: { id: userId } }"
:class="{ active: isActive }"
>
User Profile
</RouterLink>
</nav>
</template>Route Guards
Global Guards
javascript
// Before each navigation
router.beforeEach((to, from, next) => {
const isAuthenticated = checkAuth()
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login')
} else {
next()
}
})
// After each navigation
router.afterEach((to, from) => {
document.title = to.meta.title || 'My App'
})
// Before navigation error
router.onError((error) => {
console.error('Navigation error:', error)
})Per-Route Guards
javascript
const routes = [
{
path: '/admin',
component: Admin,
meta: { requiresAuth: true, role: 'admin' },
beforeEnter: (to, from, next) => {
const user = store.state.user
if (user.role !== 'admin') {
next('/unauthorized')
} else {
next()
}
}
}
]In-Component Guards
vue
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteLeave((to, from, next) => {
const answer = window.confirm('Do you really want to leave?')
if (answer) {
next()
} else {
next(false)
}
})
onBeforeRouteUpdate((to, from, next) => {
// Called when route changes but same component is reused
fetchData(to.params.id).then(() => next())
})
</script>Route Meta Fields
javascript
const routes = [
{
path: '/admin',
component: Admin,
meta: {
requiresAuth: true,
role: 'admin',
title: 'Admin Dashboard'
}
}
]
// Access meta in guards
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login')
} else {
next()
}
})Lazy Loading
javascript
const routes = [
{
path: '/about',
component: () => import('@/views/About.vue')
},
{
path: '/admin',
component: () => import('@/views/admin/Dashboard.vue')
}
]Router View
vue
<template>
<div>
<RouterView />
</div>
</template>
<!-- With named views -->
<template>
<div>
<RouterView name="sidebar" />
<RouterView name="main" />
</div>
</template>Accessing Route Information
vue
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params)
console.log(route.query)
console.log(route.meta)
console.log(route.path)
console.log(route.name)
</script>
<template>
<div>
<p>Current route: {{ route.path }}</p>
<p>Query params: {{ route.query }}</p>
</div>
</template>Dynamic Routing
javascript
// Adding routes dynamically
router.addRoute({
path: '/new-route',
component: NewRoute
})
// Adding nested routes
router.addRoute('parent', {
path: 'new-child',
component: NewChild
})
// Removing routes
router.removeRoute('routeName')Navigation Guards with Data Fetching
javascript
const routes = [
{
path: '/post/:id',
component: Post,
beforeEnter: async (to, from, next) => {
try {
const post = await fetchPost(to.params.id)
to.params.post = post
next()
} catch (error) {
next('/error')
}
}
}
]Hash vs History Mode
javascript
// History mode (recommended)
const router = createRouter({
history: createWebHistory(),
routes
})
// Hash mode
const router = createRouter({
history: createWebHashHistory(),
routes
})404 Page
javascript
const routes = [
// ... other routes
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
}
]Scroll Behavior
javascript
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
}
})Vue Router 4 provides a flexible and powerful routing solution for Vue 3 applications with excellent TypeScript support and composition API integration.