Routing in Vue 2
A route defines a mapping between a URL path and a component. The Vue Router manages multiple such routes.
Basic Setup
-
Install the router:
npm install vue-router -
Register the plugin and mount the router:
import Vue from 'vue'; import App from './App.vue'; import VueRouter from 'vue-router'; import appRouter from './router'; Vue.use(VueRouter); Vue.config.productionTip = false; new Vue({ render: h => h(App), router: appRouter }).$mount('#app'); -
Define routes in
src/router/index.js:import VueRouter from 'vue-router'; import AboutPage from '../pages/About.vue'; import HomePage from '../pages/Home.vue'; const appRouter = new VueRouter({ routes: [ { path: '/about', component: AboutPage }, { path: '/home', component: HomePage } ] }); export default appRouter; -
Use
<router-link>for navigation:<router-link active-class="highlight" to="/about">About</router-link> -
Render matched components with
<router-view>:<router-view></router-view>
Key Notes
- Route-specific components typically reside in a
pages/directory. - Inactive route component are destroyed by default unless wrapped in
<keep-alive>. - Each component has access to
$route(current route info) and$router(global router instance).
Nested Routes
Use the children property for sub-routes:
{
path: '/home',
component: HomePage,
children: [
{ path: 'news', component: NewsView },
{ path: 'messages', component: MessagesView }
]
}
Navigation requires full paths:
<router-link to="/home/news">News</router-link>
Query Parameters
Pass parameters via query string:
<!-- String syntax -->
<router-link to="/detail?id=123&title=Hello">Go</router-link>
<!-- Object syntax -->
<router-link :to="{ path: '/detail', query: { id: 123, title: 'Hello' } }">Go</router-link>
Access them using:
this.$route.query.id;
this.$route.query.title;
Named Routes
Assign names to simplify navigation:
{
name: 'userProfile',
path: '/user/:id',
component: ProfileView
}
Then navigate by name:
<router-link :to="{ name: 'userProfile', params: { id: 456 } }">Profile</router-link>
Params Parameters
Declare dynamic segments in the path:
{ path: 'detail/:userId/:category', component: DetailView }
Pass params only via named routes:
<router-link :to="{ name: 'detailView', params: { userId: 789, category: 'tech' } }">Detail</router-link>
⚠️ When using
paramswith object-based navigation,pathcannot be used—onlyname.
Access via:
this.$route.params.userId;
this.$route.params.category;
Props Passing
Enable cleaner component interfaces by passing route data as props:
- Static props:
props: { mode: 'preview' } - Dynamic from params:
props: true - Function-based:
props(route) { return { id: route.query.id, tag: route.query.tag }; } // Destructured shorthand props({ query: { id, tag } }) { return { id, tag }; }
Component recieves these as standard props:
export default {
props: ['id', 'tag'],
mounted() {
console.log(this.id);
}
}
Replace Navigation
Prevent adding a new history entry:
<router-link replace to="/settings">Settings</router-link>
Programmatic Navigation
Navigate with out <router-link>:
this.$router.push({ name: 'profile', params: { id: 101 } });
this.$router.replace({ path: '/login' });
this.$router.go(-1); // back
this.$router.forward();
Component Caching
Preserve component state with <keep-alive>:
<keep-alive include="[ 'NewsView', 'MessagesView' ]">
<router-view />
</keep-alive>
The
includevalue matches the component’snameoption.
Activation Lifecycle Hooks
Route-aware components support:
activated()— when component becomes activedeactivated()— when component is no longer active
Navigation Guards
Control access and side effects during navigation.
Global guards:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login');
} else {
next();
}
});
router.afterEach((to) => {
document.title = to.meta.title || 'My App';
});
Per-route guard:
{
path: '/admin',
component: AdminPanel,
beforeEnter: (to, from, next) => {
if (isAdmin()) next();
else next('/unauthorized');
}
}
In-component guards:
beforeRouteEnter(to, from, next) { /* ... */ },
beforeRouteLeave(to, from, next) { /* ... */ }
History Modes
- Hash mode (
#in URL): Works without server config; less clean URLs. - History mode (clean URLs): Requires server fallback to serve
index.htmlfor all client-side routes to avoid 404s on refresh.
Project Deployment
Build the project:
npm run build
This generates a dist/ folder. To serve it locally:
-
Install Express:
npm install express -
Create a server script (
server.js):const express = require('express'); const app = express(); app.use(express.static('dist')); app.get('/api/data', (req, res) => { res.json({ message: 'Hello from backend!' }); }); app.listen(3000, () => { console.log('Server running on http://localhost:3000'); }); -
Run the server:
node server.js
Popular UI Libraries
For Mobile:
For Desktop: