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
- How to install the router and create it.
- The three history modes.
- How
RouterLinkandRouterViewwork. - How to style the active link.
- How to read the address with
useRoute(). - How to read params and query.
- Optional, repeatable and pattern params, and a 404 page.
- Nested routes and named views.
- Moving by code with
push,replaceandgo.
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
| Mode | Address looks like | Server setup needed | Use for |
|---|---|---|---|
createWebHistory() | /menu | Yes: send every path to index.html | Most real websites |
createWebHashHistory() | /#/menu | No | Simple static hosting |
createMemoryHistory() | Not shown in the bar | No | Tests 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/menulink 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/3and/dish/7both 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.routeis reactive. Use it incomputedor the template.- Going from
/dish/1to/dish/2reuses the same component. Its setup code does not run again. So read params incomputedorwatch, 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/menuand/menu/drinks. - Repeatable param:
/tags/:tags+matches/tags/veg/spicy.tagsis 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 bycomponents: { default, side }. - Route props:
props: truepasses params as props, so the component does not needuseRoute(). - 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
RouterViewchanged 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 withapp.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
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
<a href> for inner links | Normal links are fine | Use <RouterLink to> | The whole page reloads and state is lost |
Forgetting <RouterView /> | Pages appear by themselves | Add <RouterView /> where pages go | Links change the address, the page stays blank |
| Reading params once in setup | Setup runs on every param change | Use computed or watch | The page shows the old dish |
| Web history with no server rule | It works on any host | Send every path to index.html | Refreshing /menu gives a 404 |
| No catch-all route | Unknown pages show nothing harmful | Add /:pathMatch(.*)* | A blank page and a warning |
router.push with path and params | Params fill in the path | Use name with params | Params are ignored |
Nested route without an inner RouterView | Children show by themselves | Add <RouterView /> in the parent page | Child pages never appear |
Check Yourself
Exercises
What to Remember
- Routes map paths to components.
RouterViewshows the match. - Use
RouterLink, never a plain<a>, for pages inside the app. useRoute()reads params and query. Read them incomputed.useRouter()moves:push,replace,go.- Add a catch-all 404 route, and a server rule for web history.
Next: Navigation Guards and Advanced Routing