Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Use A Router To Navigate Between Pages In A Vue.js Application

TwitterFacebookRedditLinkedInHacker News

When building a modern web application, being able to navigate between pages is a necessity. Not to mention it is very important to be able to do so easily. To make this possible, frameworks such as Angular, React, and Vue use what’s known as a router and a set of routes. Each possible point of navigation, or page, is a route with its own configuration.

We’re going to see how to configure a set of routes and navigate between them using Vue.js and the vue-router library.

If you’ve been keeping up with my content, you’ll remember I wrote something on the topic of navigation using Angular titled, Navigating a Web Application with the Angular Router. While being a completely different framework, some of the concepts carry over to Vue.js.

Creating a New Vue.js Project with the Vue CLI

For simplicity, we’re going to create a fresh Vue.js project and work our way into a navigation example. For this particular example we’ll be using the Vue CLI to scaffold our project, so make sure it is installed and ready to go.

From the command line, execute the following:

vue init webpack router-project

During the project initialization, it doesn’t matter if you use standalone mode (runtime and compiler) or just runtime mode. Make sure that the vue-router is installed as we’ll be using it going forward. The linter and test packages are optional as we won’t be exploring them in this example.

Once the project has been created, execute the following:

cd router-project
npm install

At this point in time we can start the development of our Vue.js web application.

Creating Pages and Configuring the Router

The Vue CLI will have created us a HelloWorld.vue file in the src/components directory. Go ahead and rename that file from HelloWorld.vue to page1.vue.

Open the project’s src/components/page1.vue file and include the following code:

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'Page1',
        data () {
            return {
                msg: 'Welcome to Your Vue.js App'
            }
        }
    }
</script>

<style scoped>
    h1, h2 {
        font-weight: normal;
    }

    ul {
        list-style-type: none;
        padding: 0;
    }

    li {
        display: inline-block;
        margin: 0 10px;
    }

    a {
        color: #42b983;
    }
</style>

You’ll notice that the above code is just a stripped down version of what we got from scaffolding our project. Inside the <script> tags, we did rename our component to Page1. This name will be important when we configure the router.

Copy the src/components/page1.vue file to src/components/page2.vue. Our second route will more or less be the same as our first because we like to keep our examples simple.

The code in src/components/page2.vue should look like the following:

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'Page2',
        data () {
            return {
                msg: 'Hey Nic Raboy'
            }
        }
    }
</script>

<style scoped>
    h1, h2 {
        font-weight: normal;
    }

    ul {
        list-style-type: none;
        padding: 0;
    }

    li {
        display: inline-block;
        margin: 0 10px;
    }

    a {
        color: #42b983;
    }
</style>

In the above code we’ve changed the component name and the message so it is obvious that we’ve navigated somewhere new. Nothing complicated has been added or changed that is different from the initial scaffold.

This is where the router configuration comes into play.

Open the project’s src/router/index.js file and include the following code:

import Vue from 'vue'
import Router from 'vue-router'
import Page1 from '@/components/page1'
import Page2 from '@/components/page2'

Vue.use(Router)

export default new Router({
    routes: [
        {
            path: "/",
            redirect: {
                name: "Page1"
            }
        },
        {
            path: '/page1',
            name: 'Page1',
            component: Page1
        },
        {
            path: '/page2',
            name: 'Page2',
            component: Page2
        }
    ]
})

So what exactly is happening in the above router file?

First we’re importing the two components that we have Page1 and Page2. Each of these components will be a route in our application, so they must be added to the routes array of our new router.

Instead of setting Page1 as our default route, the logical choice is to redirect to it when the application loads at the root. Each route in the array receives a path, a name, and a matching component. The path is what shows in the URL bar and future navigation can happen either based on the path or the name.

Per the Vue CLI and the project scaffolding, the router is wired up via the project’s src/main.js file. Now we can worry about navigation within the application.

We have two components and two possible routes so it makes sense to navigate back and forth between them. Navigation can happen via markup or via JavaScript. We’re going to explore both possibilities.

Open the project’s src/components/page1.vue file. Within the <template> section, we’re going to have the following:

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
        <router-link to="/page2">Navigate to Page2</router-link>
    </div>
</template>

Notice in the above markup we have a <router-link> tag. We’re saying that when the element is clicked, Vue will navigate to the router path indicated.

If you wanted to navigate based on the route name, the tag could easily be changed to the following:

<router-link :to="{ name: 'Page2' }">Navigate to Page2</router-link>

So that was navigation in Vue.js via markup. How about navigation via the JavaScript code?

Open the project’s src/components/page2.vue file and change the <script> block to look like the following:

<script>
    import router from '../router'

    export default {
        name: 'Page2',
        data () {
            return {
                msg: 'Hey Nic Raboy'
            }
        },
        methods: {
            navigate() {
                router.push({ name: "Page1" });
            }
        }
    }
</script>

In the above code, notice that we’ve imported the file that contains our route configuration. With it, we can create a method called navigate that will push a new navigation item into the stack. This time we’re navigating to Page1.

We need something to call this navigate method. Jump back to the <template> block and make it look like the following:

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
        <a style="cursor: pointer; text-decoration: underline" v-on:click="navigate()">Navigate to Page1</a>
    </div>
</template>

Notice that we have a v-on:click event to call the navigate method.

If you haven’t noticed, the push that we did navigates forward in the navigation stack. This means that even though we navigated to Page1 from Page2, we actually navigated to Page1, rather than back to Page1. This can be corrected by changing our navigate method to the following:

methods: {
    navigate() {
        router.go(-1);
    }
}

We can define exactly how many positions backwards we want to go.

Conclusion

You just saw how to configure and navigate between routes using the vue-router library in a Vue.js web application. Navigation can happen via markup or JavaScript code and whether or not the intention is to go backwards or forward can easily be defined.

In a future tutorial, we’ll explore how to pass data between routes during a navigation event. This is useful when creating master-detail type scenarios.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.