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

Navigate Nested Child Routes In A Vue.js Web Application

TwitterFacebookRedditLinkedInHacker News

Not too long ago I had written a few tutorials around navigation in a Vue.js web application. I had written about navigating between routes as well as passing data between routes in the form of route parameters and query parameters.

When developing a web application with a successful user interface, you’re going to want to recycle as many features as possible. Using Vue.js, it is possible to create a multiple level UI by assigning child routes to a parent route within the application. This opens the door to new possibilities in navigation.

We’re going to see how to use nested routes in a Vue.js web application by assigning child routes and views.

While it will be useful to check out my previous navigation article, it won’t be absolutely necessary because we’re going to brush up on a few of the topics.

Create a Fresh Vue.js Project with the Vue CLI

For simplicity, we’re going to start by creating a fresh Vue.js project. Assuming you have the Vue CLI installed, execute the following command:

vue init webpack nested-project

Answer the questions as prompted by the CLI. It doesn’t matter if you choose to use a standalone project or a runtime-only project. What does matter is that you install the vue-router library.

When the project scaffold is created, execute the following commands to finish things off:

cd nested-project
npm install

At this point we can start developing our parent and child routes in preparation for some awesome UI functionality.

Adding Components to Represent Parent and Child Routes

With a fresh CLI generated project, you should have a src/components/HelloWorld.vue file. We can leave it as is, but to keep the flow of this example, it will be easier to understand if we rename it to src/components/page1.vue. This component is going to represent our parent view.

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

<template>
    <div class="page1">
        <h1>{{ msg }}</h1>
        <router-view></router-view>
    </div>
</template>

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

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

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

The above code is essentially what we get when scaffolding the project. However, in the <template> block notice that we’ve included <router-view> tags. These tags act as a pass-through for any route that we define. Our child view will pass through these tags.

If you open the project’s src/App.vue file, you’ll notice that it also has <router-view> tags. The parent routes pass through these tags in the src/App.vue file.

When using <router-view> tags, it is important to note that they cannot be at the root level of the <template> block. In other words, this will not work:

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

Instead, the <router-view> tags must be inside a <div> element or something similar.

With the parent view out of the way, let’s focus on the very similar child view that we plan on nesting. Create a src/components/child1.vue file within the project and include the following code:

<template>
    <div class="child1">
        <p>{{ footnote }}</p>
    </div>
</template>

<script>
    export default {
        name: 'Child1',
        data () {
            return {
                footnote: 'Created by The Polyglot Developer'
            }
        }
    }
</script>

<style scoped></style>

The above code will just display a line of text. The goal is to have it display alongside whatever the previous parent view is displaying.

With the two components out of the way, let’s focus on wiring the routes together with the vue-router library.

Designing the Vue.js Router

All routes for this particular example will be found in the project’s src/router/index.js file. If you open it, you’ll notice it is still referencing the HelloWorld.vue file that we had previously renamed. We’re just going to change up the entire file.

Within the project’s src/router/index.js file, include the following:

import Vue from 'vue'
import Router from 'vue-router'
import Page1 from '@/components/page1'
import Child1 from '@/components/child1'

Vue.use(Router)

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

In the above code you’ll notice that we’re using the redirects that we explored in the previous article. If you run the project, you’ll notice that when you navigate to the root of the application, you’ll be redirected to http://localhost:8080/#/page1/child1 and both the parent and nested child view data will be rendered tot he screen.

Awesome right?

This isn’t the only way to accomplish rendering child routes. For example, a default child route could be configured to prevent having to directly navigate to the child path.

Take note of the following changes to the src/router/index.js file:

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

Vue.use(Router)

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

In the above code we’ve removed the name on the parent route and blanked out the child path attribute. Now, when navigating to the http://localhost:8080/#/page1 path, the child is rendered. The need to navigate directly to its path is removed.

Conclusion

You just saw how to include nested child routes in your Vue.js web application. Having nested children are useful when it comes to templating, among other things. For example, imagine having a settings section of your application where there are multiple settings categories. The settings section could be one of many parent routes while each category could be a child to that parent.

If you’re interested in learning more about navigation in a Vue.js application, check out my previous article titled, Use a Router to Navigate Between Pages in a Vue.js Application. If you’d like to know how to pass data between these pages, check out my article titled, Pass Data Between Routes in a Vue.js Web Application.

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.