Vue router: routing and navigation guards
What is Vue Router?
Vue Router is the official routing library for Vue.js. It maps URL paths to components, enables navigation, and supports guards for access control.
Basic Setup
typescript
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('@/views/Home.vue') },
{ path: '/about', component: () => import('@/views/About.vue') },
{ path: '/users/:id', component: () => import('@/views/UserProfile.vue') },
{ path: '/:pathMatch(.*)*', component: () => import('@/views/NotFound.vue') },
],
})
export default routerDynamic Routes
vue
<!-- UserProfile.vue -->
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// /users/42 → route.params.id = "42"
</script>
<template>
<h1>User {{ route.params.id }}</h1>
</template>Programmatic Navigation
vue
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function goToUser(id: number) {
router.push({ path: \`/users/\${id}\` })
// or with named routes:
router.push({ name: 'user', params: { id } })
}
function goBack() {
router.back()
}
</script>Navigation Guards
Global Guards
typescript
// router/index.ts
router.beforeEach((to, from) => {
const isAuthenticated = checkAuth()
if (to.meta.requiresAuth && !isAuthenticated) {
return { path: '/login', query: { redirect: to.fullPath } }
}
})
// Route meta
{
path: '/dashboard',
component: Dashboard,
meta: { requiresAuth: true }
}Per-Route Guards
typescript
{
path: '/admin',
component: Admin,
beforeEnter: (to, from) => {
if (!isAdmin()) return '/unauthorized'
}
}In-Component Guards
vue
<script setup>
import { onBeforeRouteLeave } from 'vue-router'
onBeforeRouteLeave((to, from) => {
if (hasUnsavedChanges.value) {
return window.confirm('You have unsaved changes. Leave anyway?')
}
})
</script>Nested Routes
typescript
{
path: '/dashboard',
component: DashboardLayout,
children: [
{ path: '', component: DashboardHome }, // /dashboard
{ path: 'settings', component: Settings }, // /dashboard/settings
{ path: 'profile', component: Profile }, // /dashboard/profile
],
}vue
<!-- DashboardLayout.vue -->
<template>
<div>
<Sidebar />
<main>
<RouterView /> <!-- Child routes render here -->
</main>
</div>
</template>Lazy Loading (Code Splitting)
typescript
// Each route is a separate chunk — loaded on demand
const routes = [
{
path: '/dashboard',
component: () => import('@/views/Dashboard.vue'),
},
{
path: '/admin',
component: () => import('@/views/Admin.vue'),
},
]Summary
| Feature | API |
|---|---|
| Access current route | useRoute() |
| Navigate programmatically | useRouter().push() |
| Global guard | router.beforeEach() |
| Per-route guard | beforeEnter in route config |
| In-component guard | onBeforeRouteLeave() |
| Lazy loading | () => import(...) |
Important:
Vue Router provides file-based-like routing via configuration, dynamic segments with params, and powerful navigation guards for authentication and access control. Always use lazy loading (() => import()) for route components to optimize bundle size.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.