Vue.js Router Configuration
Introduction
Vue Router is the official routing library for Vue.js applications. It enables you to build single-page applications with navigation between different views without page reloads. Proper router configuration is essential for creating well-structured Vue applications with intuitive navigation.
In this tutorial, you'll learn how to set up Vue Router in your project, define routes, use navigation guards, and implement advanced configuration options. By the end, you'll have a solid understanding of how to configure routing in your Vue.js applications.
Prerequisites
Before starting, you should have:
- Basic knowledge of Vue.js
- Node.js and npm installed
- A Vue.js project created (using Vue CLI or Vite)
Installing Vue Router
First, let's install Vue Router in your project:
# Using npm
npm install vue-router@4
# Using Yarn
yarn add vue-router@4
Vue Router 4 is designed for Vue 3, while Vue Router 3 is for Vue 2. Make sure to install the version that matches your Vue version.
Basic Router Setup
Creating Router Instance
To set up Vue Router, you need to create a router instance in a dedicated file. Let's create a file called router/index.js
:
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
// Define routes
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: AboutView
}
]
// Create router instance
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router
Connecting Router to Vue App
Next, you need to connect the router to your Vue application by updating your main.js
file:
// src/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')
Adding Router View
In your App.vue
file, add the <router-view>
component to display the appropriate component for the current route:
<!-- src/App.vue -->
<template>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view />
</template>
Now, the router will render the appropriate component based on the current URL path.
Route Configuration Options
Basic Route Structure
Each route in Vue Router typically includes these properties:
{
path: '/route-path', // URL path
name: 'routeName', // Optional name for programmatic navigation
component: Component, // Component to render
props: true, // Pass route params as component props
meta: { requiresAuth: true } // Additional data
}
Route Parameters
You can define dynamic route parameters using a colon syntax:
// src/router/index.js
const routes = [
// ... other routes
{
path: '/user/:id',
name: 'user',
component: UserView
}
]
The parameter value will be accessible in your component via $route.params.id
or as a prop if you set props: true
.
Nested Routes
Vue Router supports nested routes using the children
property:
// src/router/index.js
const routes = [
{
path: '/users',
component: UserLayout,
children: [
{ path: '', component: UserList }, // /users
{ path: ':id', component: UserDetails }, // /users/:id
{ path: ':id/edit', component: UserEdit } // /users/:id/edit
]
}
]
In the parent component (UserLayout
), you need to add another <router-view>
where the child components will be rendered:
<!-- UserLayout.vue -->
<template>
<div class="user-container">
<h1>User Section</h1>
<router-view /><!-- Child routes will render here -->
</div>
</template>
Lazy Loading Routes
For better performance in larger applications, you can load components asynchronously when they're needed:
const routes = [
{
path: '/about',
name: 'about',
// Using dynamic import for lazy loading
component: () => import('../views/AboutView.vue')
}
]
This technique, called "code-splitting," improves initial load time by loading components only when they're needed.
Navigation Guards
Navigation guards are hooks provided by Vue Router to control navigation. There are three types:
Global Guards
Global guards affect all routes and are defined directly on the router instance:
const router = createRouter({
// ... router configuration
})
// Execute code before each route navigation
router.beforeEach((to, from) => {
// Check if the route requires authentication
if (to.meta.requiresAuth && !isAuthenticated()) {
// Redirect to login page
return { name: 'login' }
}
})
// Execute code after each route navigation
router.afterEach((to, from) => {
document.title = to.meta.title || 'My Vue App'
})
Route-Specific Guards
You can define guards for specific routes:
const routes = [
{
path: '/admin',
component: AdminDashboard,
beforeEnter: (to, from) => {
// Check if user is admin
if (!isAdmin()) {
return false // Cancel navigation
}
}
}
]
Component Guards
You can also define guards inside components:
<script>
export default {
beforeRouteEnter(to, from, next) {
// Called before the component is created
// "this" is not available here
next(vm => {
// Access component instance via "vm"
})
},
beforeRouteUpdate(to, from) {
// Called when the route changes but the component is reused
// "this" is available
this.userData = fetchUserData(to.params.id)
},
beforeRouteLeave(to, from) {
// Called when navigating away from this component
if (this.formHasChanges && !confirm('Discard changes?')) {
return false // Cancel navigation
}
}
}
</script>
Advanced Router Configuration
HTML5 History Mode
Vue Router supports two history modes:
// HTML5 History Mode (clean URLs)
const router = createRouter({
history: createWebHistory(),
routes
})
// Hash Mode (URLs with #)
const router = createRouter({
history: createWebHashHistory(),
routes
})
HTML5 mode provides clean URLs but requires server configuration. Hash mode works without server configuration but adds #
to URLs.
Route Aliasing
Aliases allow multiple paths to render the same component:
const routes = [
{
path: '/home',
component: Home,
alias: ['/main', '/homepage'] // /main and /homepage will also render Home
}
]
Named Routes and Views
Named routes make programmatic navigation easier:
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function navigateToUser(userId) {
router.push({ name: 'user', params: { id: userId }})
}
</script>
Named views allow rendering multiple components at the same route:
const routes = [
{
path: '/dashboard',
components: {
default: DashboardMain,
sidebar: DashboardSidebar,
header: DashboardHeader
}
}
]
Then in your template:
<template>
<router-view name="header" />
<router-view name="sidebar" />
<router-view /> <!-- default -->
</template>
Passing Props to Route Components
Instead of accessing the route params through $route
, you can pass them as props:
const routes = [
// Props as boolean: passes route.params as props
{
path: '/user/:id',
component: User,
props: true
},
// Props as object: passes static props
{
path: '/static',
component: Static,
props: { staticProp: 'hello' }
},
// Props as function: for custom logic
{
path: '/search',
component: Search,
props: route => ({ query: route.query.q })
}
]
This makes your components more reusable and testable.
Practical Example: Building a Blog Router
Let's build a router configuration for a blog application:
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/HomeView.vue')
},
{
path: '/blog',
component: () => import('../views/BlogLayout.vue'),
children: [
{
path: '',
name: 'blog-list',
component: () => import('../views/BlogList.vue')
},
{
path: 'category/:category',
name: 'blog-category',
component: () => import('../views/BlogCategory.vue'),
props: true
},
{
path: ':id',
name: 'blog-post',
component: () => import('../views/BlogPost.vue'),
props: true,
beforeEnter: (to) => {
// You could verify the post exists
const postExists = checkIfPostExists(to.params.id)
if (!postExists) {
return { name: 'not-found' }
}
}
}
]
},
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue')
},
{
path: '/admin',
name: 'admin',
component: () => import('../views/AdminView.vue'),
meta: { requiresAuth: true }
},
// Catch-all route for 404 pages
{
path: '/:pathMatch(.*)*',
name: 'not-found',
component: () => import('../views/NotFoundView.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
// Scroll to top of the page on route change
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
}
})
// Global navigation guard
router.beforeEach((to, from) => {
// Check if route requires authentication
if (to.meta.requiresAuth && !isAuthenticated()) {
return {
name: 'login',
query: { redirect: to.fullPath }
}
}
})
function isAuthenticated() {
// This would be your authentication logic
return localStorage.getItem('token') !== null
}
function checkIfPostExists(id) {
// This would check if a post exists
// Simulated for this example
return true
}
export default router
This configuration includes:
- Lazy-loaded components for better performance
- Nested routes for the blog section
- Route parameters for blog posts and categories
- Navigation guards for authentication
- A catch-all route for 404 pages
- Scroll behavior configuration
Summary
In this tutorial, you've learned how to configure Vue Router in your Vue.js applications. We've covered:
- Basic router setup and installation
- Defining routes with various configuration options
- Using route parameters and nested routes
- Implementing navigation guards at global, route, and component levels
- Advanced configuration options like history modes, aliasing, and named views
- Building a practical router configuration for a blog application
Vue Router is a powerful tool that gives you granular control over navigation in your Vue applications. By mastering its configuration options, you can create more organized, maintainable, and user-friendly applications.
Additional Resources
Exercises
- Create a router configuration for a simple e-commerce site with product listing, product detail, cart, and checkout pages.
- Implement authentication in a Vue application using navigation guards.
- Build a nested route structure for a user dashboard with multiple sections.
- Create a route configuration that uses URL query parameters to filter a list of items.
- Implement route transitions using Vue's transition components with the router.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)