How to setup Vue-Router 2.0: Basic Setup

vuejs setup vue-router 2spa

VueJS is an awesome framework. It has two-way data binding and it’s easy to get started. The best part is its capability to be a SPA. We can make a SPA using Vue’s Vue-Router plugin.

In this example, we’ll:

  1. Start a new VueJS 2.0 project.
  2. Install Vue Router 2.0.
  3. Put together routes.
  4. Make a page.
  5. Make a default redirection.

This is part 1 of a three part article series discussing Vue-Router 2.0.

For faster setup of a VueJS project, I use the Vue-CLI and the Webpack template. If you don’t have the Vue-CLI:


npm install -g vue-cli

Start a new VueJS 2.0 project


vue init webpack <myproject>

The Vue-CLI will have prompts. After the usual ones like project name, description and author, there are choices to customize your Vue project. To help better grasp things for this example, we’ll use Runtime-only:

Use runtime-only on Vue-CLI prompt. Basic Vue-Router 2 SPA

To make this example simpler, we’ll type n for the prompts ESLint, unit tests and e2e tests.

Choose No for all unit testing, Karma, mocha and eslint to make things simplier Basic Vue-Router 2 SPA

The VueJS Webpack template has been generated. Go to the project folder:


cd <myproject>

The Webpack template has a package.json that has all the dependencies needed to get your VueJS project started. All you have to do is type:


npm install

Note: The dependencies installation can take some time. But it’s worth the wait.

After a successful installation, run the project:


npm run dev

Install Vue Router 2.0

In the dependencies property of package.json, only Vue 2.0 was installed. To make a SPA we need to install the Vue-Router.


npm install vue-router --save.

Setup a router file.

Create a router.js file in the src folder.

The router.js file will have the routes declaration for page components and any redirection definitions. For other SPA-rich features, the route related code should be placed in this file (if possible). Structural organization will help in the long run.

A basic router.js file should look like this:


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

/* Page Component imports here */

/* Hook up Vue-Router to Vue */
Vue.use(VueRouter);

/* Make the router instance */
var Router = new VueRouter();

export default Router;

Make a page component.

Make a pages folder inside the src folder. This directory will have all the page components.

Instead of putting/saving all the components in the components folder (that came with the Webpack template), we should put the pages in its own pages folder. Having a pages folder helps to differentiate page components from other VueJS components. The components folder includes components such as a custom modal component or a loading spinner component. These types of components are what’s imported into and as part of a page.

Again, structural organization can help a lot.

The first page component will be Page1.vue.


<template>
<h1>Page 1</h1>
</template>

<script>
export default {
}
</script>

Put together routes

Time to setup route definitions in the router.js. First, import Page1.vue in router.js.


/* Page Component imports here */
import Page1 from './pages/Page1';

var routes = [{
   path: '/p1',
   name: 'Page1',
   component: Page1
}];

In the above code, we created a routes variable, and it is an array of objects. The object is composed of properties path, name, and component. The path and component are very important while name is optional. As you can see, component points to Page1 component that we just created in the pages folder and imported in the router.js file. The path is a string, and it can be anything. For this example, it’s /p1 so that we can type in the browser localhost:8080/#/p1. And, the contents of Page1.vue should show.

Include the routes as a property in the Vue Router instance.


var Router = new VueRouter({
   routes
});

The router.js file setup is coming long. But this VueJS project doesn’t know about Page1.vue file and the router.js file. Let’s include these files to the main.js file.

In the Webpack template, the main.js is responsible for rendering the VueJS app. We need to modify the main.js file to register the Router instance declared in the router.js file.

In main.js file, import the Router instance.


import Router from './router';

Include this router instance in the Vue object.


new Vue({
  el: '#app',
  Router,
  render: h => h(App)
});

We need to modify the App.vue so that we can access Page1.vue; To show Page1.vue, we use <router-view>. The <template> part of the App.vue file should now look like this:


<template>
<div id="app">
  <router-view></router-view>
</div>
</template>

The <router-view> component is globally injected. It comes with the Vue-Router 2.0. We use it to show the page components.

route is undefined error

If you go to your browser’s console log. You see this error.

VueRouter route is undefined error. Basic Vue-Router 2 SPA

This error just means that we didn’t correctly register the Vue Router instance in the Vue instance (that’s in the main.js).

The reason why there is this error is because I’m attempting to use the short-hand that’s a new Javascript feature; The Vue instance expects a router property. However, JavaScript is case-sensitive. This means that Router and router are not the same thing.

There are two solutions to fix this error.

The first solution is to change how we import the Vue Router instance. So, we can change Router to router. This way we can use the short-hand. The short-hand is just short for { router: router }. Instead of that, we can type just { router }. Now, if we type http://localhost:8080/#/p1 in the browser, we don’t see the error and the contents of Page1.vue appears.

The second solution is if we want to keep Router instead of router, we can use the traditional JavaScript way like this:


new Vue({
 el: '#app',
  router: Router,
  render: h => h(App)
});

I don’t have any preference to this yet. I’m still a bit of a JavaScript traditionalist but I’m not against any modern changes that can make my development process easier.

Fragment Instance Error (Additional).

You might get a Fragment Instance Error if you modified the original App.vue template to not have an enclosing <div> like this:


<template>
<router-view></router-view>
</template>

This is why it’s important to have an enclosing <div id="app"> around the <router-view>.


<template>
<div id="app">
  <router-view></router-view>
</div>
</template>

Redirecting:

In this example, our first page component’s path is /p1. So the URL must have /p1 in order to see the Page1.vue contents. But you have to type it in the browser. To show Page1 as the default page, we can setup a redirection.

In router.js, we’ll add another JSON object in the routes array:


var routes = [{
  path: '/p1',
  component: 'Page1'
},
 /* Add this! */
 {
  path: '*', redirect: '/p1'
}];

So when the URL is only localhost:8080, Page1 will show up. If the URL is localhost:8080/p2, but the path p2 doesn’t exist, contents of Page1 will show up as default.

Conclusion

Vue Router is the easiest JavaScript router I’ve ever used. It doesn’t take much to set it up. And, it doesn’t take much to make a SPA. Redirection is straightforward. This article talked about structural organization. But that is definitely just a suggestion.

Next article will be about how to navigate between page components.