Vue Router Basics
Introduction
Vue Router adds client-side routing to Vue apps—change URLs without full page reloads, map paths to components, and pass route params. This chapter sets up createRouter, <RouterLink>, <RouterView>, dynamic segments, and programmatic navigation with useRouter.
Prerequisites
- Environment and create-vue Project with Vue Router enabled (or
npm install vue-router) - Components: Props and Emits
Router Setup
src/router/index.ts (typical create-vue layout):
src/main.ts:
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
createApp(App).use(router).mount("#app");src/App.vue:
<template>
<header>
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
</header>
<main>
<RouterView />
</main>
</template>Code explanation:
createWebHistoryuses real URLs (/about)—needs server fallback in productionRouterViewrenders the matched route componentRouterLinkrenders<a>with active class handling
Compare with Navigation and History in JavaScript—Router wraps the History API.
Active Links
<RouterLink to="/" active-class="nav-active" exact-active-class="nav-exact">
Home
</RouterLink>router-link-active / router-link-exact-active default classes.
Dynamic Route Params
{
path: "/posts/:slug",
name: "post-detail",
component: () => import("../views/PostDetailView.vue"),
}PostDetailView.vue:
<script setup lang="ts">
import { computed } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
const slug = computed(() => route.params.slug as string);
</script>
<template>
<h1>Post: {{ slug }}</h1>
</template>route.params updates when navigating /posts/a → /posts/b on same component—watch slug or use onBeforeRouteUpdate.
Programmatic Navigation
| Method | Behavior |
|---|---|
router.push() | Navigate; adds history entry |
router.replace() | Navigate without new history entry |
router.back() | History back |
Query String
router.push({ path: "/search", query: { q: "vue", page: "2" } });
// /search?q=vue&page=2Read query:
const q = computed(() => route.query.q as string | undefined);Nested Routes
Layout with child pages:
{
path: "/dashboard",
component: () => import("../layouts/DashboardLayout.vue"),
children: [
{ path: "", name: "dashboard-home", component: () => import("../views/DashboardHome.vue") },
{ path: "settings", name: "dashboard-settings", component: () => import("../views/DashboardSettings.vue") },
],
},DashboardLayout.vue:
<template>
<div class="dashboard">
<aside>
<RouterLink to="/dashboard">Overview</RouterLink>
<RouterLink to="/dashboard/settings">Settings</RouterLink>
</aside>
<section>
<RouterView />
</section>
</div>
</template>Child routes render in nested <RouterView />.
Named Views (Awareness)
Multiple <RouterView name="sidebar"> for complex layouts—see official docs; one default view is enough for most apps.
Route Props (Optional)
Pass params as component props:
{
path: "/posts/:id",
component: PostView,
props: true,
}<script setup lang="ts">
defineProps<{ id: string }>();
</script>404 Catch-All
{
path: "/:pathMatch(.*)*",
name: "not-found",
component: () => import("../views/NotFoundView.vue"),
}Place last in routes array.
History Mode vs Hash
| Mode | URL | Server config |
|---|---|---|
History (createWebHistory) | /about | SPA fallback required |
Hash (createWebHashHistory) | /#/about | No special config |
Production SPAs usually prefer history + Nginx try_files—Build and Deploy.
Practice Exercise
Add routes:
/posts— list view/posts/:slug— detail view- Link from list to detail with
RouterLink
FAQ
RouterLink vs <a href>?
<a> causes full page reload; RouterLink client navigation.
Component not updating on param change?
Same component reused—**watch route.params or key <RouterView :key="route.fullPath">.
Lazy import syntax?
() => import('./View.vue') code-splits route—Lazy Routes.
BASE_URL?
Vite import.meta.env.BASE_URL for apps hosted in subdirectory.
Multiple RouterView?
Nested routes use one per level in layout components.
Without create-vue router?
npm install vue-router, create router/index.ts, app.use(router).