Vue3 Routing (Vue Router)

In this chapter, we will introduce Vue routing.

Vue routing allows us to access different content through different URLs.

With Vue, we can implement multi-view single-page web applications (SPA).

Vue.js routing requires loading thevue-router library

Chinese documentation URL:vue-router documentation。

Vue Router is responsible for mapping URL paths to components in the application. When users navigate in the app, the URL updates but the page does not reload, providing a smooth user experience.

The figure above shows atwo-level nested route structure:

  • top-level (App.vueof<router-view>)responsible for renderingstandalone layouts(such asLogin.vue) ormain frame layout(Layout.vue)。
  • main frame layout (Layout.vue)internally contains a second<router-view>, used to renderchild components of the feature page(such asDashboard.vue、User.vue), thus achieving persistent display of the header, sidebar, and footer.
  • Unmatched paths will eventually lead to an independentpage404.vue。

Core Components

Component Description Options API Access Composition API Access
routerInstance An instance of the entire routing system, used for global navigation, adding routes, etc. this.$router useRouter()
routeObject The currently active route state object, containing information such as the current URL, parameters, query, etc. this.$route useRoute()
<router-link> A component used for navigation in the application; it will be rendered as an<a>tag, but can prevent the default page reload. - -
<router-view> The component matched by the route will be rendered in this position. - -

Installation

npm Installation

npm install vue-router

npm (China Mirror)

It is recommended to use the Taobao mirror:

npm install -g cnpm --registry=https://registry.npmmirror.com
cnpm install vue-router@4

Direct Download / CDN

https://unpkg.com/vue-router@4

Basic Usage

1. Create a routing table

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

export default createRouter({
  history: createWebHistory(),
  routes
})

2. Mount in the application

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

3. Page outlet

<router-view></router-view>

4. Navigation

<router-link to="/about">About</router-link>

5. Dynamic Routing

{ path: '/user/:id', component: User }

Visiting /user/10, $route.params.id === '10'.

6. Lazy Loading

const About = () => import('../views/About.vue')

7. Navigation Guards (Authentication)

router.beforeEach((to, from, next) => {
  next()
})

8. Redirect

{ path: '/old', redirect: '/' }

9、404

{ path: '/:pathMatch(.*)*', component: NotFound }

Simple Example

Vue.js + vue-router can easily implement a single-page application.

<router-link>is a component used to set up a navigation link to switch between different HTML content.toThe `to` attribute is the target address, i.e., the content to be displayed.

In the following example, we add vue-router, then configure component and route mappings, and then tell vue-router where to render them. The code is as follows:

HTML Code

<div id="app"> <h1>Hello App!</h1> <p> <!--Use the router-link component for navigation--> <!--Specify the link by passing `to`--> <!--`<router-link>` will render an `<a>` tag with the correct `href` attribute--> <router-link to="/">Go to Home</router-link> <router-link to="/about">Go to About</router-link> </p> <!--Router View--> <!--The component matched by the route will be rendered here.--> <router-view></router-view> </div>

router-link

Note that we did not use a regular `<a>` tag, but instead used a custom component `router-link` to create links. This allows Vue Router to change the URL without reloading the page and handle URL generation and encoding. We will see later how to benefit from these features.

router-view

`router-view` will display the component corresponding to the URL. You can put it anywhere to suit your layout.

JavaScript Code

//1. Define route components. //They can also be imported from other files. const Home = { template: '<div>Home</div>' } const About = { template: '<div>About</div>' } //2. Define some routes //Each route needs to map to a component. //We'll discuss nested routes later. const routes = [ { path: '/', component: Home }, { path: '/about', component: About }, ] //3. Create the router instance and pass the `routes` configuration //You can add more configuration here, but for now we are //keeping it simple for now. const router = VueRouter.createRouter({ //4. Internally, a history mode implementation is provided. For simplicity, we use hash mode here. history: VueRouter.createWebHashHistory(), routes, //Shorthand for `routes: routes` }) //5. Create and mount the root instance. const app = Vue.createApp({}) //Make sure to _use_ the router instance so that //the entire app supports routing. app.use(router) app.mount('#app') //Now, the application has started!

Try it »

Clicked navigation links will have styles addedclass ="router-link-exact-active router-link-active"。

Application Example

The following example covers the routing'sDefinition、Creation、Mounting、NavigationandRenderingfive core steps.

1. main.js (entry file)

Example

import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // Import the configured router instance

// 1. Create a Vue application instance
const app = createApp(App);

// 2. Mount the router
app.use(router);

// 3. Mount to the DOM
app.mount('#app');

2. router/index.js (route configuration)

Example

import { createRouter, createWebHistory } from 'vue-router';

// Import route components (using synchronous imports to simplify the example)
const Home = { template: '<h2>Home Page</h2><p>Welcome to the application home!</p>' };
const About = { template: '<h2>About Us</h2><p>Learn more about this project.</p>' };

// Define the array of route records
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  // 404 match (put it last)
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: { template: '<div>404 Not Found</div>' }
  }
];

// Create the Router instance
const router = createRouter({
  // Use HTML5 History mode (recommended)
  history: createWebHistory(),
  routes, // Route configuration
});

export default router;

3. App.vue (root component)

Example

<template>
  <div>
    <h1>Vue Router Example</h1>
   
    <nav>
      <router-link to="/" active-class="active-link">Home</router-link> |
      <router-link to="/about" active-class="active-link">About</router-link> |
      <router-link to="/nonexistent">404 Demo</router-link>
    </nav>
   
    <hr>
   
    <main>
      <router-view></router-view>
    </main>
  </div>
</template>

<style>
/* Simple active styles */
.active-link {
  font-weight: bold;
color: #427EB9; /* Vue green */
}
/* Adjust link spacing */
nav a {
  margin: 0 5px;
  text-decoration: none;
}
</style>

When you run this application:

  • ClickHomelink, the URL changes to/,<router-view>displays inHome Pagecomponent content.
  • ClickAboutlink, the URL changes to/about,<router-view>displays inAbout Uscomponent content.
  • Click404 Demolink, the URL changes to/nonexistent,<router-view>displays in404 Not Foundcomponent content.

<router-link> Related Attributes

Next, let's learn more about the attributes of <router-link>.

to

Represents the link to the target route. When clicked, the value of `to` will be passed to `router.push()` immediately, so this value can be a string or an object describing the target location.

<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home.html">Home</a>

<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>

<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>

<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

replace

If the replace attribute is set, clicking will call router.replace() instead of router.push(), and no history record will be left after navigation.

<router-link :to="{ path: '/abc'}" replace></router-link>

append

When the append attribute is set, the path is prepended to the current (relative) path. For example, if we navigate from /a to a relative path b, without append the path is /b, with append it is /a/b.

<router-link :to="{ path: 'relative/path'}" append></router-link>

tag

Sometimes you want<router-link>to render as a certain tag, for example<li>.tagSo we use

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>

active-class

prop to specify which tag. It still listens for clicks and triggers navigation.

<style>
   ._active{
      background-color : red;
   }
</style>
<p>
   <router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

Set the CSS class name used when the link is active. It can be replaced by the following code.classNote hereactive-class="_active"。

exact-active-class

use

<p>
   <router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

event

Configure the class that should be active when the link is exactly matched. It can be replaced by the following code.

<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>

The above code sets the event to mouseover, and when the mouse moves over Router Link 1, the navigated HTML content will change.


Vue Router (v4, Vue 3) Core API Handbook

I.createRouterConfiguration Options

Configuration Item Purpose Example
history Specify URL mode createWebHistory()
routes Route table definition array [{ path: '/', component: Home }]
scrollBehavior Control page scroll position { top: 0 }
strict Whether to strictly distinguish trailing slashes true
linkActiveClass Class when link is active 'active'
linkExactActiveClass Class when link is exactly active 'exact-active'
parseQuery Custom URL query parsing (q) => ({...})
stringifyQuery Custom URL query serialization (obj) => 'a=1'

II. History Factory

API Purpose Example
createWebHistory() Use HTML5 History mode (recommended) createWebHistory()
createWebHashHistory() Use Hash mode (URL contains#) createWebHashHistory()
createMemoryHistory() Suitable for SSR (server-side rendering) createMemoryHistory()

III.RouteRecord(Route Record)

Field Purpose Example
path Route path definition /user/:id
name Route naming name: 'User'
component Corresponding main component UserView
components For named views (multiple<router-view>) { default: A, left: B }
redirect Redirect target redirect: '/login'
children Define nested child routes [ { path: 'profile' } ]
props willparamsAutomatically convert to componentprops props: true
meta Custom meta information field { auth: true }
alias Add aliases for the current route (multiple entries) alias: '/b'
beforeEnter Route-specific navigation guard { beforeEnter: (to,from,next)=>{} }

IV. Router Navigation (Router Instance Methods)

Router API Purpose Example
router.push(to) Programmatic navigation, adds a new record to the history stack router.push('/a')
router.replace(to) Programmatic navigation, replaces the current history record router.replace('/a')
router.back() Go back one step router.back()
router.forward() Go forward one step router.forward()
router.go(n) Manually offset the history stack router.go(-1)
router.addRoute(route) Dynamically add route records router.addRoute({ name:'Post', ... })
router.removeRoute(name) Remove route records by name router.removeRoute('user')
router.getRoutes() Get all route records router.getRoutes()
router.hasRoute(name) Determine whether a route with the specified name exists router.hasRoute('user')

V. Navigation Guards

Guard Scope Hook signature
router.beforeEach Global before (to, from, next) => {}
router.beforeResolve Global resolve phase (after in-component guards and async components are resolved) (to, from, next) => {}
router.afterEach Global after (cannot prevent navigation) (to, from, failure) => {}
beforeEnter Route-specific beforeEnter: (to, from, next) => {}
beforeRouteEnter In-component (cannot accessthis) beforeRouteEnter(to, from, next) {}
beforeRouteUpdate In-component (when the current route is reused, e.g., param changes) beforeRouteUpdate(to, from, next) {}
beforeRouteLeave In-component (when leaving this component) beforeRouteLeave(to, from, next) {}

VI.<router-link>Props

Props Purpose Example
to Target route address to="/a"or:to="{ name: 'user', params: { id: 1 } }"
replace Use during navigationrouter.replace() <router-link replace>
custom Custom rendering, used with slots <router-link custom v-slot="{ href }">
active-class Class applied when link is active 'active'
exact-active-class Class applied when link is exactly matched 'exact'

VII.<router-view>Props

Props Purpose Example
name Used for multi-view (named view) rendering <router-view name="left">
route (Advanced) Forcefully specify the route object to render <router-view :route="someRoute">

VIII.Route(Current Route Object)

This object is obtained throughuseRoute()orthis.$routeobtained.

Field Type Meaning Example
params object Dynamic path parameters route.params.id
query object URL query parameters route.query.q
hash string Hash value in the URL (with#) route.hash
fullPath string Full resolved path (including query and hash) /user/1?x=1
name string Name of the current route 'User'
path string Current path (without query and hash) /user/1
meta object In the route configuration'smetainformation route.meta.auth
matched RouteRecord[] All records matched by the route (for nested routes) route.matched

IX. Composition API

API Purpose Example
useRoute() Get the current route object (Route) const route = useRoute()
useRouter() Get the router instance (Router) const router = useRouter()

X. Programmatic Navigation (Complete Example)

Purpose Example Remarks
Named route navigation router.push({ name:'User', params:{ id:10 } }) Recommended method, does not depend on path order
Navigation with query parameters router.push({ path:'/search', query:{ q:'x' } }) Path + query parameters
Awaitable push/replace await router.push('/a') Navigation is asynchronous, you can await its completion
URL object navigation router.push({ path: '/foo', hash: '#bar' }) Full control over URL details
Other extensions