How to setup Vue-Router 2.0: Basic Setup
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:
- Start a new VueJS 2.0 project.
- Install Vue Router 2.0.
- Put together routes.
- Make a page.
- 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:
To make this example simpler, we’ll type n
for the prompts ESLint, unit tests and e2e tests.
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.
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.