Vue Router 4 is in beta and it’s subject to change.
To build a single page app easily, we got to add routing so that URLs will be mapped to components that are rendered.
In this article, we’ll look at how to use Vue Router 4 with Vue 3.
Catch-All / 404 Not Found Route
We can create a catch-all or 404 route by using the asterisk pattern as the path.
For example, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
<title>App</title>
</head>
<body>
<div id="app">
<p>
<router-link to="/foo">Foo</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Foo = {
template: "<div>foo</div>"
};
const NotFound = {
template: "<div>not found</div>"
};
const routes = [
{ path: "/foo", component: Foo },
{ path: "/:catchAll(.*)", component: NotFound }
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes
});
const app = Vue.createApp({});
app.use(router);
app.mount("#app");
</script>
</body>
</html>
We define a catch-all route with the /:catchAll(.*)
capture group instead of *
as in Vue Router 3.
Now when we go to any path that isn’t foo
, we’ll see the ‘not found’ message.
Nested Routes
We can create nested routes with the children
property.
For instance, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
<title>App</title>
</head>
<body>
<div id="app">
<p>
<router-link to="/parent/home">parent</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Parent = {
template: `<div>
parent
<router-view></router-view>
</div>`
};
const Home = {
template: `<div>home</div>`
};
const routes = [
{
path: "/parent",
component: Parent,
children: [{ path: "home", component: Home }]
}
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes
});
const app = Vue.createApp({
watch: {
$route() {
console.log(this.$route.resolve);
}
}
});
app.use(router);
app.mount("#app");
</script>
</body>
</html>
We have a routes
array with an object that has the children
property.
The property has an object with the path
and component
properties like a regular route.
In the router-link
, the to
prop has the path to the nested route.
The Parent
component has the router-view
component so that we can view the content of the child route.
Therefore, when we click on the parent link, we see the:
parent
home
text displayed.
We can have URL parameters in the parent route.
For example, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
<title>App</title>
</head>
<body>
<div id="app">
<p>
<router-link to="/parent/1/home">parent</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Parent = {
template: `<div>
<div>parent {{ $router.currentRoute.value.params.id }}</div>
<div><router-view></router-view></div>
</div>`
};
const Home = {
template: `<div>home</div>`
};
const routes = [
{
path: "/parent/:id",
component: Parent,
children: [{ path: "home", component: Home }]
}
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes
});
const app = Vue.createApp({
watch: {
$route() {
console.log(this.$route.resolve);
}
}
});
app.use(router);
app.mount("#app");
</script>
</body>
</html>
To add the :id
URL parameter placeholder.
Since the router-link
‘s to
prop is now /parent/1/home
and we have the $router.currentRoute.value.params.id
in the Parent
‘s template, we’ll see the number 1 displayed.
The URL parameter placeholder of the parent stays with the parent.
Conclusion
The way we define 404 and nested routes are slightly different from Vue Router 3 in Vue Router 4.