Skip to content

Router

Routing allows the user to switch between pages without refreshing the page. This is what makes navigation easy and really nice in your web applications.

Vue-router is something you use to make single-page applications seem like multiple different pages.

The big benefit of using these together is that, once the page loads the first time, you have everything unless you have to make server calls to the database or something later. That means pages, or “views”, load very fast and even make page transitions both possible and pretty easy.

Vue Router is the official router for Vue.js. It deeply integrates with Vue.js core to make building Single Page Applications with Vue.js a breeze.

Features include:

  • Nested route/view mapping
  • Modular, component-based router configuration
  • Route params, query, wildcards
  • View transition effects powered by Vue.js' transition system
  • Fine-grained navigation control
  • Links with automatic active CSS classes
  • HTML5 history mode or hash mode, with auto-fallback in IE9
  • Customizable Scroll Behavior

Live example

See the jsfidle example here: https://jsfiddle.net/yyx990803/xgrjzsup/


How to

When adding Vue Router to the mix, all we need to do is map our components to the routes and let Vue Router know where to render them.

Here's a basic example:

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- use router-link component for navigation. -->
    <!-- specify the link by passing the `to` prop. -->
    <!-- `<router-link>` will be rendered as an `<a>` tag by default -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- route outlet -->
  <!-- component matched by the route will render here -->
  <router-view></router-view>
</div>
// 0. If using a module system (e.g. via vue-cli), import Vue and VueRouter
// and then call `Vue.use(VueRouter)`.

// 1. Define route components.
// These can be imported from other files
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. Define some routes
// Each route should map to a component. The "component" can
// either be an actual component constructor created via
// `Vue.extend()`, or just a component options object.
// We'll talk about nested routes later.
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. Create the router instance and pass the `routes` option
// You can pass in additional options here, but let's
// keep it simple for now.
const router = new VueRouter({
  routes // short for `routes: routes`
})

// 4. Create and mount the root instance.
// Make sure to inject the router with the router option to make the
// whole app router-aware.
const app = new Vue({
  router
}).$mount('#app')
// Now the app has started!

By injecting the router, we get access to it as this.$router as well as the current route as this.$route inside of any component:

// Home.vue
export default {
  computed: {
    username() {
      // We will see what `params` is shortly
      return this.$route.params.username
    }
  },
  methods: {
    goBack() {
      window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
    }
  }
}

Dynamic route matching

Very often we will need to map routes with the given pattern to the same component. For example we may have a User component which should be rendered for all users but with different user IDs.

In vue-router we can use a dynamic segment in the path to achieve that:

const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
    // dynamic segments start with a colon
    { path: '/user/:id', component: User }
  ]
})

Now URLs like /user/foo and /user/bar will both map to the same route.

A dynamic segment is denoted by a colon :.

When a route is matched, the value of the dynamic segments will be exposed as this.$route.params in every component. Therefore, we can render the current user ID by updating User's template to this:

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

Catch all / 404 routes

Regular params will only match characters in between url fragments, separated by /.

If we want to match anything, we can use the asterisk *:

{
  // will match everything
  path: '*'
}
{
  // will match anything starting with `/user-`
  path: '/user-*'
}

When using asterisk routes, make sure to correctly order your routes so that asterisk ones are at the end. The route { path: '*' } is usually used to 404 client side.


Programmatic Navigation

Aside from using <router-link> to create anchor tags for declarative navigation, we can do this programmatically using the router's instance methods.

Inside of a Vue instance, you have access to the router instance as $router. You can therefore call this.$router.push.

To navigate to a different URL, use router.push. This method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL.

This is the method called internally when you click a <router-link>, so clicking <router-link :to="..."> is the equivalent of calling router.push(...).

Declarative Programmatic
<router-link :to="..."> router.push(...)

The argument can be a string path, or a location descriptor object.

Examples:

// literal string path
router.push('home')

// object
router.push({ path: 'home' })

// named route
router.push({ name: 'user', params: { userId: '123' } })

// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' } })

Note

Params are ignored if a path is provided, which is not the case for query, as shown in the example above.

Instead, you need to provide the name of the route or manually specify the whole path with any parameter:

const userId = '123'
router.push({ name: 'user', params: { userId } }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// This will NOT work
router.push({ path: '/user', params: { userId } }) // -> /user

Read more