Vue Router Basics

By Syncfusion®, Inc. · Last updated

Installing Vue Router, createRouter() and history modes, routes, RouterLink and RouterView, active link classes, useRouter() and useRoute(), params and query, optional, repeatable and pattern params, nested routes, named views, route props, named routes, redirects, aliases, a 404 page, and push, replace and go.

Pages in a Single-Page App

  • A Single-Page App (SPA) loads one HTML page, then swaps content without a full reload.
  • Users still expect real addresses: /menu, /dish/3, the Back button, bookmarks.
  • Vue Router = the official library that links addresses to components.
  • When the address changes, the router shows the matching component.

Simple lesson: Vue Router maps addresses to components without reloading the page.

A Real-World Example

  • Meera's site has three pages: Home, Menu and About.
  • Clicking a link must change the address and the page, with no reload.
  • The Back button must work too.
  • What happened: each link changed the address bar and the page below it.
  • The active link turned bold and green. Back and Forward in the bar work.

What You Will Learn

  1. How to install the router and create it.
  2. The three history modes.
  3. How RouterLink and RouterView work.
  4. How to style the active link.
  5. How to read the address with useRoute().
  6. How to read params and query.
  7. Optional, repeatable and pattern params, and a 404 page.
  8. Nested routes and named views.
  9. Moving by code with push, replace and go.

Setting Up the Router

  • Install it in a real project: npm install vue-router. create-vue can add it for you.
  • createRouter({ history, routes }) makes the router.
  • Each route is an object: { path: "/menu", component: MenuPage }.
  • app.use(router) installs it. The router is a plugin, as you saw in Composables, Directives and Plugins.
  • Put page components in a views/ folder.

Animation: a click on a RouterLink changes the address to /menu. The router finds the matching route in the list and shows MenuPage inside RouterView

/ /menu

routes

/ → HomePage /menu → MenuPage /about → AboutPage

HomePage MenuPage

Address changes → the router finds the route → RouterView shows its component

The address picks the route. RouterView shows the route's component.

History Modes

ModeAddress looks likeServer setup neededUse for
createWebHistory()/menuYes: send every path to index.htmlMost real websites
createWebHashHistory()/#/menuNoSimple static hosting
createMemoryHistory()Not shown in the barNoTests and server rendering

With createWebHistory(), a real server must answer every path with index.html. You will set this up in Errors, Security and Deployment. In this lab, the preview has no real address bar, so web history is kept in memory and shown in a small bar above the app.

RouterLink and RouterView

  • <RouterLink to="/menu"> renders an <a> that changes the page without a reload.
  • <RouterView /> is where the current route's component appears.
  • The link to the current page gets the class router-link-exact-active.
  • A link to a parent of the current page gets router-link-active. For /menu/3, the /menu link has it.

Simple lesson: routes in createRouter(), links with RouterLink, pages in RouterView.

Params and Query

  • Dynamic segment = a part of the path that changes, written with a colon: /dish/:id.
  • /dish/3 and /dish/7 both match. The value is a param.
  • Query = the part after ?: /menu?veg=1&sort=price.
  • useRoute() gives the current route: route.params.id, route.query.veg.
  • route is reactive. Use it in computed or the template.
  • Going from /dish/1 to /dish/2 reuses the same component. Its setup code does not run again. So read params in computed or watch, not once at the top.

Going from /dish/1 to /dish/3 reuses the same component. Code in <script setup> does not run again. Read params in computed, or watch them. You will see more in Navigation Guards and Advanced Routing.

Moving by Code

  • useRouter() gives the router itself.
  • router.push("/menu") goes to a page and adds a history entry.
  • router.replace("/menu") goes without adding an entry. Back skips it.
  • router.go(-1) goes back one step. go(1) goes forward.
  • Named route = a route with a name. Push with { name: "dish", params: { id: 2 } }. The path can change later without breaking links.

Simple lesson: useRoute() reads the address. useRouter() changes it.

Prefer named routes in links and push: { name: "dish", params: { id: 2 } }. If the path changes from /dish/:id to /menu/:id later, every named link keeps working.

Matching Patterns

  • Optional param: /menu/:category? matches /menu and /menu/drinks.
  • Repeatable param: /tags/:tags+ matches /tags/veg/spicy. tags is an array.
  • Pattern param: /order/:id(\\d+) matches only digits.
  • Catch-all: /:pathMatch(.*)* matches anything. Put a 404 page there.
  • Routes are ranked by how specific they are, not by their order.

Nested Routes, Named Views, Props, Redirects and Aliases

  • Nested routes: a route has children. Its component holds its own <RouterView />.
  • Named views: several <RouterView name="side" /> on one page, filled by components: { default, side }.
  • Route props: props: true passes params as props, so the component does not need useRoute().
  • Redirect: { path: "/home", redirect: "/" } sends one path to another.
  • Alias: { path: "/menu", alias: "/food" } shows the same page at a second address.
  • What happened: / redirected to /account.
  • The account page stayed. Only the inner RouterView changed between tabs.
  • On order 501, a second, named view showed help on the side.

Simple lesson: children for pages inside pages, named views for several areas, props: true for clean components.

TL;DR

  • Vue Router = the official router. Links addresses to components.
  • createRouter({ history, routes }) = makes the router. Install with app.use(router).
  • History modes = web (/menu), hash (/#/menu), memory (no address).
  • <RouterLink to> / <RouterView /> = links without reload / where the page appears.
  • Active classes = router-link-active, router-link-exact-active.
  • useRoute() = route.params, route.query, route.path.
  • useRouter() = push, replace, go.
  • Patterns = :id?, :tags+, :id(\d+), /:pathMatch(.*)* for 404.
  • Nested / named / props = children, <RouterView name>, props: true.

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
<a href> for inner linksNormal links are fineUse <RouterLink to>The whole page reloads and state is lost
Forgetting <RouterView />Pages appear by themselvesAdd <RouterView /> where pages goLinks change the address, the page stays blank
Reading params once in setupSetup runs on every param changeUse computed or watchThe page shows the old dish
Web history with no server ruleIt works on any hostSend every path to index.htmlRefreshing /menu gives a 404
No catch-all routeUnknown pages show nothing harmfulAdd /:pathMatch(.*)*A blank page and a warning
router.push with path and paramsParams fill in the pathUse name with paramsParams are ignored
Nested route without an inner RouterViewChildren show by themselvesAdd <RouterView /> in the parent pageChild pages never appear

Check Yourself

Exercises

What to Remember

  • Routes map paths to components. RouterView shows the match.
  • Use RouterLink, never a plain <a>, for pages inside the app.
  • useRoute() reads params and query. Read them in computed.
  • useRouter() moves: push, replace, go.
  • Add a catch-all 404 route, and a server rule for web history.

Next: Navigation Guards and Advanced Routing