Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.
In this article, we’ll look at how to define nested routes with Vue Router.
Why do we Need Nested Routes?
We need nested routes to organize routes where components are nested multiple levels deep.
For example, we have to find a way to organize routes like:
/user/bar/profile
/user/bar/posts
into one coherent place.
Defining Nested Routes
We can define nested routes by adding a children
array in the route entry, and then in the parent route’s template we have to add router-view
to display the children routes.
For example, we can write the following:
src/index.js
:
const Profile = { template: "<p>{{$route.params.user}}'s profile</p>" };
const Posts = { template: "<p>{{$route.params.user}}'s posts</p>" };
const User = {
template: `
<div>
<p>user - {{$route.params.user}}</p>
<router-view></router-view>
</div>
`
};
const routes = [
{
path: "/user/:user",
component: User,
children: [
{ path: "posts", component: Posts },
{ path: "profile", component: Profile }
]
}
];
const router = new VueRouter({
routes
});
new Vue({
el: "#app",
router
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="[https://unpkg.com/vue/dist/vue.js](https://unpkg.com/vue/dist/vue.js)"></script>
<script src="[https://unpkg.com/vue-router/dist/vue-router.js](https://unpkg.com/vue-router/dist/vue-router.js)"></script>
</head>
<body>
<div id="app">
<div>
<router-link to="/user/foo">Foo User</router-link>
<router-link to="/user/foo/posts">Foo Post</router-link>
<router-link to="/user/foo/profile">Foo Profile</router-link>
</div>
<router-view></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
In the code above, we have:
const routes = [
{
path: "/user/:user",
component: User,
children: [
{ path: "posts", component: Posts },
{ path: "profile", component: Profile }
]
}
];
to define the child routes.
The Posts
and Profile
components are like any component we defined as usual.
However, the User
component has the router-view
to display them content of the Posts
and Profile
components.
In the template, we have 3 router links to go to the root and child routes:
<router-link to="/user/foo">Foo User</router-link>
<router-link to="/user/foo/posts">Foo Post</router-link>
<router-link to="/user/foo/profile">Foo Profile</router-link>
Then we should see:
Foo User Foo Post Foo Profile
user - foofoo's posts
when we go to /#/user/foo/posts
or click on Foo Post
.
And we should see:
Foo User Foo Post Foo Profileuser - foofoo's profile
when we go to /#/user/foo/profile
or click on Foo Profile
.
When we go to /#/user/foo
or click on Foo User
, we see:
Foo User Foo Post Foo Profileuser - foo
Any nested path that starts with /
will be treated as the root path. This lets us use component nesting without having to use a nested URL.
Also, the parent and child routes all have access to the same route parameters.
For example, we can add a UserHome
component and a route for it to the example above as follows:
src/index.js
:
const Profile = { template: "<p>{{$route.params.user}}'s profile</p>" };
const Posts = { template: "<p>{{$route.params.user}}'s posts</p>" };
const UserHome = { template: "<p>{{$route.params.user}} home</p>" };
const User = {
template: `
<div>
<p>user - {{$route.params.user}}</p>
<router-view></router-view>
</div>`
};
const routes = [
{
path: "/user/:user",
component: User,
children: [
{ path: "", component: UserHome },
{ path: "posts", component: Posts },
{ path: "profile", component: Profile }
]
}
];
const router = new VueRouter({
routes
});
new Vue({
el: "#app",
router
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<div>
<router-link to="/user/foo">Foo User</router-link>
<router-link to="/user/foo/posts">Foo Post</router-link>
<router-link to="/user/foo/profile">Foo Profile</router-link>
</div>
<router-view></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
Now when we go to /user/foo
or click on Foo User
, we see:
Foo User Foo Post Foo Profileuser - foofoo home
Everything else remains the same.
Conclusion
We can add nested routes to our routes by adding a children
property with an array of routes.
Then we have to add router-view
to the parent route so that we can see the content of the child routes.
The parent and child routes all have access to the same route parameters.