Jordan Irabor Software developer || Machine learning enthusiast || Gamer || Artist || Deep thinker

Router options compared: Vue Router, Voie, Vue-routisan and Vue-route

Spoiler alert, you should probably be using Vue Router

9 min read 2576

Introduction

The arrival of modern web frameworks has changed the way developers think and build software. We can now use flexible frameworks (with really cool names) — such as Angular, React and Vue — to easily whip up appealing interfaces.

Some benefits of working with modern front-end frameworks include:

  • A template system
  • Progressive web application (PWA) features
  • Reactivity (data-binding)
  • Optimization
  • Routing
  • Single Page Applications (SPA)

Each framework has a unique way of solving problems but the general concept of a framework regulates the fundamental similarities amongst them. In this article, we will look at client-side routing, its importance and Vue Router — our preferred router for Vue applications.

SPA’s are web applications that display dynamic content within the space of a single page throughout the duration of the interaction. SPA’s work by neatly replacing the user interface of the application as the user switches from page to page.

A SPA knows how to make these page transitions using a router. The router is responsible for the synchronicity between the URL address bar and the interface being displayed. In web development, there have been two fundamental methods for rendering content to the web browser:

  1. Client-side
  2. Server-side

With the server-side method, the client makes a request to a server whenever new content is expected. The obvious downside to this is it can be wastefully repetitive in its interaction with the back-end resource. The good side — it is great for SEO because crawler bots are supplied with content to index.

With the client-side method, the web application will initially request a page from the back-end server — index.html — then after that first request, additional data will be fetched dynamically (using an [XHR](https://www.w3schools.com/xml/xml_http.asp) object). The application’s further routing will be handled by client-side JavaScript.

Let’s define our subject of discussion — routers:

A router is a tool that synchronizes the currently displayed view with the address bar. In other words, it’s the component of a modern web application that triggers the update for the view when there has been a change to the URL address.

We will be considering Vue as the progressive JavaScript framework of interest. It has an official router module called Vue Router. This router is constantly being maintained by the same people who maintain the Vue framework.

What is Vue Router?

Vue Router is the official router for Vue. It deeply integrates with Vue core to make building SPAs with Vue a breeze. Some features of Vue Router are:

Let’s find out some of the benefits of Vue Router by setting it up and working with it.

Working with Vue Router

Although there are a number of ways to set up a Vue project, our preferred method for this tutorial is the vue-cli. The vue-cli gives us the benefit of being able to quickly scaffold and serve Vue projects. We are going to use the latest version of the tool (version 3) as at the time of writing this article — if you do not already have it installed, you can install it here.

Creating a new project

We can create a new Vue project with this command:

vue create routerapp

You will be prompted to pick a preset, choose default (babel, eslint).

Installing Vue Router

Let’s add Vue Router to our project:

npm install vue-router

Note: This would be yarn add vue-router if you use Yarn. If you prefer to use Vue via a script tag, you can include Vue Router with this script: <script src="https://unpkg.com/vue-router"></script>

Configuring the router

We have successfully installed Vue Router but there is no way for Vue to know about its existence. We will explicitly tell Vue to use Vue Router in the src/main.js file:

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import routes from './routes'

Vue.use(VueRouter)
const router = new VueRouter({
  routes
})

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

Note: Your IDE might display an error if you try to save but this is only because we haven’t created the — routes — folder yet. We will create it next, so ignore the error for now.

We have included a reference to a folder — ./routes — that hasn’t been created yet. This folder will contain a file where we will define the routes and the views they map to.

We called Vue.use() and passed in the VueRouter object so that we have access to the router in any component. Let’s create the routes folder within the src directory. We will also create an index.js file within the src/routes folder where our route definitions will be saved.

Open the src/routes/index.js file and paste in the following snippet:

import Home from '../components/Home'
import About from '../components/About'

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

Note: Just as before, we have referenced a few files that are yet to be created. Ignore any lint errors for now. We will create these view files very soon.

In the code snippet above, we have defined a few routes and their views. We imported two component views (we will create these soon) and added them as components in the routes array. This is how we define new routes with Vue Router.

Building the components

Let’s create the Home and About components:

  1. The Home component is the default component we want users to see on page load
  2. The About component displays some information about the application

Create a home.vue file within the components directory and paste in the following snippet:

<template>
 <div class="home">
   <h2>THIS IS THE HOME VIEW</h2>
 </div>
</template>
<script>

export default {
 name: "home"
};

</script>
<style scoped>
.home {
 width: 100%;
 height: 50vh;
 background: rgb(25, 169, 241);
}
h2 {
 padding: 15px 0px 0px 0px;
 margin: 0px;
 text-align: center;
 font-size: 24px;
}
</style>

Great, we’ve just defined the mark up for the homepage, now let’s create a — about.vue — file within the components directory and paste in the following content:

<template>
  <div class="about">
    <h2>THIS IS THE ABOUT VIEW</h2>
  </div>
</template>
<script>

export default {
  name: "about"
};

</script>
<style scoped>
.about {
  width: 100%;
  height: 50vh;
  background: rgb(243, 245, 145);
}
h2 {
  padding: 15px 0px 0px 0px;
  margin: 0px;
  text-align: center;
  font-size: 24px;
}
</style>

We have built both components but for us to see Vue Router’s smooth transitioning in action, we have to use the <router-view/> tag. When this tag is defined, it automatically controls which view is displayed depending on the URL address bar. Where do we put this tag?

Let’s open up the parent component — src/App.vue — and edit it so that it has two links for both components and displays the proper view using <router-view/>. Open up the file and paste in the following snippet:

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link>
      <router-link to="/about">About</router-link>
    </nav>
    <router-view/>
  </div>
</template>
<script>

export default {
  name: "app"
};

</script>
<style>

#app {
  max-width: 896px;
  margin: 0 auto;
}

nav {
  padding: 10px;
  border: 1px solid grey;
}

nav a {
  color: white;
  padding: 5px;
  background: grey;
  border-radius: 3.5px;
  text-decoration: none;
}

a:first-child {
  margin-right: 15px;
}

</style>

Let’s test the application now. Navigate into the src directory using the terminal and serve the application:

$ cd src
$ vue serve

The last command will start the development server and render the application on the local address — http://localhost:8080/ — let’s visit it on our browser:

In the screen recording above, we can see how the application toggles between the home and about pages without causing a reload to the browser’s window. This is the power of a router in a modern web framework. Let’s look at some other functions and features of Vue Router.

Switching to history mode

You’ll notice that there’s a “#” in the URL address bar of the application. This is because, by default, Vue Router uses the URL hash to simulate a full URL so that the page won’t be reloaded when the URL changes. We can toggle the mode and change it to history mode which leverages the history.pushState API to achieve URL navigation without a page reload.

Let’s switch to history mode by updating the code in the src/main.js file:

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import routes from './routes'

Vue.use(VueRouter)
const router = new VueRouter({
  mode: 'history', // add this
  routes
})

Vue.config.productionTip = false
new Vue({
  render: h => h(App),
  router
}).$mount('#app')

Great, now let’s head over to the web browser and we can see that the “#” is gone and history mode is activated:

We’ve barely explored the functions and features of Vue Router but here are a few other features for the curious:

  1. Dynamic routing
  2. Nested routes
  3. Props
  4. Route guards
  5. Keeping components alive etc

Let’s take a look at some alternatives to Vue Router in the next section.

Alternative router options for Vue

Sometimes, you might want to use a different router for your Vue application. When that is the case, here are a few alternatives worth considering:

Voie

Voie, as defined on the official npm page, is a simple router for building robust SPAs in Vue. Unlike Vue Router which is organized around URLs, Voie is organized around states. Voie-based apps are basically finite-state machines — the state is simply a named logical “place” within your application.

Each state can optionally have a:

  • URL pattern
  • Vue component
  • Enter hook to populate state with data
  • Leave hook to clean up things

States are organized into hierarchies: child states will inherit parameters and data from the parent state. If the child state has a component, it will be rendered at the location specified by the parent (or nearest ancestor) state denoted by <v-view> directive.

Let’s take a look at this example:

Note: Voie is still undergoing active development so issues reported issues will be fixed as the development progresses.

Installation

Voie can be installed with npm using the following command:

 npm i --save voie

Usage and syntax

Let’s take a look at this example:

app.add('user', {
 path: '/user/:userId',
 redirect: 'user.dashboard',   // specify "default" sub-state
 enter: (ctx) => {             // can return a Promise
   return fetch('/user/' + ctx.params.userId)
     .then(res => res.json())
     .then(data = ctx.data.user = data);
 },
 component: {
   template: '<div class="user-layout"><v-view></v-view></div>'
 }
});

app.add('user.dashboard', {
 component: {
   template: '<h1>Hello, {{ user.name }}!</h1>'
 }
});

In the snippet above, visiting /user/123 would fetch a user with id 123 from a server and then render the following markup (assuming the user has the name “Alice”):

<div class="user-layout">
  <h1>Hello, Alice!</h1>
</div>

Note: fragment instances are not supported as components. In other words, make sure all components contain a single top-level element without flow control directives (v-if, v-for, etc.)

Further learning

Visit the official npm page to learn more concepts about other Voie, including:

  • State manager
  • State definition
  • Running the state manager
  • State hierarchy
  • Navigating states
  • Enter/Leave
  • Before each / after each
  • Redirecting
  • State transitions
  • Parameters
  • History setup

Vue-routisan

A significant time in Vue’s development curve as a web framework was when Laravel started shipping with a front-end boilerplate containing Bootstrap and Vue. This led to the adoption of Vue as the preferred front-end framework of many Laravel developers. That being said, Vue-routisan is a Vue routing system based on the Laravel routing system.

Installation

We can install Vue-routisan with npm using the following command:

npm install vue-routisan

Usage and syntax

The view() method receives the path and component route options respectively. If you defined the view resolver, you may directly specify the name of the component:

Route.view('/', 'Home');

Without the view resolver, it would be:

import Home from './views/Home';
 
Route.view('/', Home);

What is the view resolver?

The view resolver allows the view() method to automatically require components for your routes. This saves you from having repetitive imports and requires when defining routes. The view resolver is optional. If you choose to not configure it, you can import a component and pass it directly as the 2nd parameter of the view() method:

import Route from 'vue-routisan';
 
Route.setViewResolver((component) => {
    return require('./views/' + component).default;
});

Named routes

The name() method sets the name option on the route instance:

Route.view('/user/profile', 'Profile').name('profile');

Nested routes

The children() method sets the children option on the route instance:

Route.view('/user', 'User').children(() => {
    Route.view('', 'UserList');
    Route.view(':id', 'UserDetails');
    Route.view(':id/edit', 'UserEdit');
});

Further learning

Visit the official npm page to learn about other Vue-routisan concepts including:

  • Route groups
  • Route Prefixes
  • Automatically formatted paths
  • Retrieving all routes
  • Navigation guards
  • Redirection routes

Vue-route

Vue-route is a routing directive for Vue.js inspired by ng-view. It allows you to declare your routes on the $root Vue object:

var root = new Vue({
    el: 'body',
 
    routes: {
        '/home': {
            componentId: 'fg-home',
            isDefault: true
        },
        '/items/:item': {
            componentId: 'fg-item',
            afterUpdate: 'updateHeader',
            data: {
                defaultColor: '#3453DD'
            }
        },
        options: {
            hashbang: true
        }
    }
});

Then you can reference it with minimal markup:

<body>
    <div v-route></div>
</body>

Installation and configuration

  • We can install Vue-route with npm using the following command:
npm i vue-route --save
  • Require and install the plugin:
var Vue = require('vue'),
    route = require('vue-route');
 
Vue.use(route);
  • Put the <div v-route></div> in your main template.
  • Pass your routes to the $root VM of your app.

Transition, keep-alive and other directives

If you want to add custom transitions between your pages, it’s recommended to put them on each page’s component template. Putting anything on the v-route element itself will only be active if you change this element (for instance with a v-if directive). Following the example, that would be:

<div class="Home" v-transition="homeTransition">...</div>

Further learning

Visit the official npm page to learn about other Vue-route concepts including:

  • Location concept
  • Route parameters
  • Subroutes

Conclusion

In this article, we learned some of the differences between client-side and server-side rendered applications. We also saw some advantages of client-side routing and how it can augment the performance of our web applications.

We further went on to learn about Vue and Vue Router (the official router for Vue) in addition to alternatives to Vue Router. If you’ve been looking to explore an alternative to Vue Router, you should try getting acquainted with one of the options listed above.

Get a Free Trial of LogRocket

or

Jordan Irabor Software developer || Machine learning enthusiast || Gamer || Artist || Deep thinker

Leave a Reply