Last update on Wednesday, March 14th 2018

Using Vue as an Angular alternative for Ionic: Routing part 1

The basic routing concepts between an Ionic Vue and an Ionic Angular application are the same.
A list of Routes are declared and they will help us navigate to different Views.

In this tutorial, we will see how to create:

  1. A basic route
  2. A route with parameters
  3. A named route
  4. Some nested views

If you don’t know how to bootstrap an Ionic Vue application, you should go to the first tutorial of the course.

As usual, we start by adding a new library:

npm i vue-router -S

The vue-router plugin is the official Vue router plugin, the equivalent of the @angular/router.

Basic example

We will start with a very basic route and pay tribute to the Ionic’s About section.

We first head to the index.html file:

  <div id="app">
    <router-link to="/about">About</router-link>

    <router-view></router-view>
  </div>

The router-view Directive will display the content according to the current route, this can be compared to a television.
The router-link helps us navigate to the about view, this is the equivalent of a remote control button.

In order to use those elements, we need to go to the main.ts file where we can link Vue and VueRouter together:

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

Vue.use(VueRouter);

We can now prepare the routing by creating a simple About Component:

const About = {
  template: "<div>About view</div>",
  mounted: function() {
    console.log("Welcome to the About view");
  },
  destroyed: function() {
    console.log("Thanks for visiting to the About view");
  }
};

This Component has a simple template and two lifecycle hooks. Thanks to the mounted and destroyed hooks, we can see the transition when navigating.

We then create an array for the routes:

const routes = [
  {
    path: "/about",
    component: About
  }
];

So far there’s not much difference between the Ionic Vue and the Ionic Angular routing system.

And we finish the configuration:

const router = new VueRouter({ routes });

const app = new Vue({ router }).$mount("#app");

A new VueRouter instance is created then used by the Ionic Vue root instance.

Routes can be more complex. Since the REST ascension, we tend to pass more optional information when navigating. We will take the previous About example and pass a user id.

Routing with params

Going back to the index.html:

  <div id="app">
    <router-link to="/about">About</router-link>
    <router-link to="/about/1">About user 1</router-link>

    <router-view></router-view>
  </div>

The second route has more information: the user’s id.

We will use this information in the About Component from the main.ts file:

const About = {
  template: "<div>About view</div>",
  mounted: function() {
    console.log("Welcome to the About view");
    const userId = this.$route.params.id;

    if (userId) {
      console.log("You are viewing the user:", userId);
    }
  },
  destroyed: function() {
    console.log("Thanks for visiting to the About view");
  }
};

The id is acquired from the context’s $route.params.id property in the mounted hook. If the id is not null, we display the optional information.

We update the routes configuration:

const routes = [
  {
    path: "/about/:id",
    component: About
  }
];

The “/:id” part means that an optional id parameter can follow the “/about” part.
Be careful there, if we want to use a more specific route like “/about/create”, it’s necessary to use this configuration:

const routes = [
  {
    path: "/about/create",
    component: About
  },
  {
    path: "/about/:id",
    component: About
  }
];

The router will first check if the route contains “/create”, if not, it will consider that the rest of the route is an id parameter. If we do the opposite, the “/create” part will always be considered an id and we will never reach the “/create” view.
Always list the routes from the more specific to the more generic (and by alphabetical order if possible). And that’s it, we have our route working!

But wait! That’s not the only way.

We can create a different Contact Component:

const Contact = {
  props: ["id"],
  template: "<div>Contact view</div>",
  mounted: function() {
    console.log("Welcome to the Contact view");
    const userId = this.id;

    if (userId) {
      console.log("You are viewing the user", userId);
    }
  },
  destroyed: function() {
    console.log("Thanks for visiting to the Contact view");
  }
};

This one has an id props and directly get the id from the context.

We only need to specify in the routes configuration that some props are available:

const routes = [
  {
    path: "/contact/:id",
    component: Contact,
    props: true
  }
];

Named routes

Routing can be quite annoying when the paths are quite long. However, thanks to named routes we can use shorter names as aliases, here is an example:

const routes = [
  {
    path: "/black",
    name: "white",
    component: NamedRoute
  }
];

This route’s path is “/black”, but it can be called by using the name “white”!
Here is the associated Component:

const NamedRoute = {
  template: "<div>Named route content</div>"
};

And how to use it in the index.html:

  <div id="app">
    <router-link :to="{name: 'white'}">Go to the same named route</router-link>

    <router-view></router-view>
  </div>

We need to use an object here with a name property, hence we need to use :to to interpret the content.

Nested views

Sometimes we can end up with just one little part of the view that requires some changes. Creating one new view for each change can be overkill.

Nested views can be useful and performant in this case. They are like a <ng-switch> coupled with an <ng-include>.
The parent’s content stays the same and the sub-views content are shown according to the current route.

Here is how it’s done:

const FirstChild = {
  template: "<div>Hi I'm the first child</div>"
};

const SecondChild = {
  template: "<div>Hi I'm the second child</div>"
};

const ParentComponent = {
  template: `<div>
      Hi I'm the parent, I will stay here
      <router-view></router-view>
      <router-link to="/parent/first-child">First Child</router-link>
      <router-link to="/parent/second-child">Second Child</router-link>
    </div>
  `
};

const ParentRoute = {
  path: "/parent",
  name: "parent",
  component: ParentComponent,
  children: [
    {
      path: "first-child",
      component: FirstChild
    },
    {
      path: "second-child",
      component: SecondChild
    }
  ]
};

const routes = [
  ParentRoute
];

The Parent Component has a <router-view> Element where its Child Components will be displayed.
We have two Child Components, they are declared in the children property and we navigate between them by using a <router-link> to “/parent/first-child” and “/parent/second-child”.

We can finally add a <router-link> to the parent in our main view:

  <div id="app">
    <router-link to="/parent">Go to the nested part</router-link>

    <router-view></router-view>
  </div>

Conclusion

Routing is a big part for an Ionic Vue application.
It can be very simple with basic routes, however, the bigger the application gets, the more complex the routing system becomes.
The routes generally follow a functional approach coupled with the REST convention like:

user/:id/delete
about/user/:id/color/:colorId

It’s wiser to take a step back and set some time aside to create a solid routing system. In the next routing tutorial, we will dive into more advanced concepts like lazy loading, dynamic routes, etc.

Using Vue as an Angular alternative for Ionic: Routing part 1

Vue as an Angular alternative for Ionic: The Components

Using Vue as an Angular alternative for Ionic: Vuex in One Go

Stay up to date


Join over 4000 other developers who already receive my tutorials and their source code out of the oven + other free stuff!