30-days-cover-image

30 Days of Vue

Vue Router

 

This post is part of the series 30 Days of Vue.

In this series, we're starting from the very basics and walk through everything you need to know to get started with Vue. If you've ever wanted to learn Vue, this is the place to start!

Vue Router

With our application scaffold established in the last article, let's use Vue's official client-side routing library, Vue Router, to enable routing in our application.

Vue Router

In order to use the Vue Router library, we'll need to first install it into our project:

npm install vue-router --save

For module based Webpack applications, we’ll need to call Vue.use(VueRouter) before we’re able to use the Vue Router library. We can write the following code and the rest of the router instantiation in a src/router.js file.

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

Before we continue, let's take a step back and from a high level look at how and why we plan to architect our application.

Conceptually, we've seen how we can create tree structures using components and nested components. Using this perspective with a single page app with routes, we can think of the different parts of a page as children. Routing in a single page app from this perspective is the idea that we can take a part of a subtree and switch it out with another subtree. We can then dynamically switch out the different trees in the browser.

For a more simpler explanation, we'll essentially need to use a Vue component that acts as a root component of the routable elements. We can then tell Vue to change a view, which can just swap out an entire Vue component for another one as though it's a completely different page rendered by a server.

Before we use this root router component, we’ll need to tell our router which views should be shown in which routes. This matching can be dictated in a routes array that we’ll create. We’ll create this array in the src/router.js file:

import Vue from 'vue';
import VueRouter from 'vue-router';
import BlastoiseCard from "./components/BlastoiseCard";
import CharizardCard from "./components/CharizardCard";
import VenusaurCard from "./components/VenusaurCard";
import NotFound from "./components/NotFound";

Vue.use(VueRouter);

const routes = [
  { path: "/", component: CharizardCard },
  { path: "/charizard", component: CharizardCard },
  { path: "/blastoise", component: BlastoiseCard },
  { path: "/venusaur", component: VenusaurCard },
  { path: "*", component: NotFound }
];

We’ve set each Pokémon path to their own respective component (e.g. /blastoise will render the BlastoiseCard component). We’ve also set the root path / to the CharizardCard component.

The path of * is how we, in Vue Router, can show a certain fallback component if the user attempts to access a route that we haven’t explicitly defined (i.e. the user is accessing a ‘Not Found’ template). Any route entered in the URL that does not exist will return the NotFound component which contains a simple header template that states 'Sorry. We couldn't find that Pokémon :('.

src/pokemon-routing/src/components/NotFound.vue
<template>
  <h3 class="subtitle has-text-white">
    Sorry. We couldn't find that Pokémon :(.
  </h3>
</template>

<script>
export default {
  name: "NotFound",
};
</script>

We can now look to create our application wide router instance using the new VueRouter({}) constructor. At the very minimum, the constructor expects the routes array that maps components to their respective pathnames:

import Vue from "vue";
import VueRouter from "vue-router";
// ...

const routes = [
  // ...
];

export const router = new VueRouter({ 
  routes
});

Vue Router’s default mode is hash. Hash mode URLs always contain a hash symbol (#) after the hostname (i.e domain name). The hash mode basically means our application routes will be displayed like this - http://localhost:8080/#/charizard. The benefit to this often lies with allowing us to have multiple client side routes without having to provide the necessary server side fallbacks.

Since our application is a dead simple client-side app and we don’t want the hash in our URLs, we can get rid of it. To remove hashes in our URLs, we’ll specify the history mode property in our router instantiation:

import Vue from "vue";
import VueRouter from "vue-router";
// ...

const routes = [
  // ...
];

export const router = new VueRouter({
  mode: 'history',
  routes
});

If we were to deploy our single-page app and depending on the server configuration we have, we may have to provide a catch-all fallback route to tell our server to always fall back to the same index.html file. The Vue Router documentation show some example server configurations we can use to create this fallback route.

When a Vue Router instance is prepared, it’s made available to a Vue application by declaring the router object within the application wide Vue instance. We’ll do this in the main.js file where our Vue app is currently being instantiated:

src/pokemon-routing/src/main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
 

This page is a preview of 30 Days of Vue

Get the rest of this chapter and 330+ pages of Vue instruction for free.

The entire source code for this tutorial series can be found in the GitHub repo, which includes all the styles and code samples.

If at any point you feel stuck, have further questions, feel free to reach out to us by:

Get Started Now Background Image

Get started now

Join us on our 30-day journey in Vue. Join thousands of other professional Vue developers and learn one of the most powerful web application development frameworks available today.

No spam ever. Easy to unsubscribe.