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 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.
In-Component Guards
The beforeRouteEnter
guard is run before the route that renders the component is confirmed
Therefore, it doesn’t have access to this
.
However, we can access it within the next
callback.
To do that, we write:
beforeRouteEnter(to, from, next) {
next(vm => {
// ...
})
}
The vm
has the route component’s instance.
The is the only route that supports passing in a callback for next
.
We can use this
directly in the beforeRouterUpdate
and beforeRouterLeave
methods, so passing in a callback to next
isn’t supported.
So we can just write:
beforeRouteUpdate (to, from, next) {
this.name = to.params.name
next()
}
or:
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave?')
if (answer) {
next()
} else {
next(false)
}
}
beforeRouteLeave
is usually used to prevent the user from accidentally leaving the route.
Navigation Resolution Flow
The steps for navigation are as follows:
- Navigation triggered.
- Call
beforeRouteLeave
guards in deactivated components. - Call global
beforeEach
guards. - Call
beforeRouteUpdate
guards in reused components. - Call
beforeEnter
in route configs. - Resolve async route components.
- Call
beforeRouteEnter
in activated components. - Call global
beforeResolve
guards. - Navigation confirmed.
- Call global
afterEach
hooks. - DOM updates are triggered.
- Run callbacks passed to
next
inbeforeRouteEnter
guards with instantiated instances.
Route Meta Fields
We can add route meta fields with the meta
property.
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>
<router-link to="/bar">bar</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Foo = {
template: "<div>foo</div>"
};
const Bar = {
template: "<div>bar</div>"
};
const routes = [
{
path: "/foo",
component: Foo
},
{
path: "/bar",
component: Bar,
meta: { requiresAuth: true }
}
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes
});
router.beforeEach((to, from, next) => {
console.log(to.meta.requiresAuth);
next();
});
const app = Vue.createApp({});
app.use(router);
app.mount("#app");
</script>
</body>
</html>
to add a meta
property to our routes
array entry.
We have an object with the requiresAuth
property.
Then in the beforeEach
callback, we can access it with the to.meta.requiresAuth
property.
Transitions
We can add transitions for route changes with Vue Router.
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>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>
</head>
<body>
<div id="app">
<p>
<router-link to="/foo">foo</router-link>
<router-link to="/bar">bar</router-link>
</p>
<router-view v-slot="{ Component }">
<transition name="fade">
<component :is="Component" />
</transition>
</router-view>
</div>
<script>
const Foo = {
template: "<div>foo</div>"
};
const Bar = {
template: "<div>bar</div>"
};
const routes = [
{
path: "/foo",
component: Foo
},
{
path: "/bar",
component: Bar
}
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes
});
const app = Vue.createApp({});
app.use(router);
app.mount("#app");
</script>
</body>
</html>
to add transitions to our app.
We add the router-view
and access the Component
slot prop to get the component that’s displayed through the router-view
.
Then we can pass that to the component
component inside the router-view
.
We set the name
prop so that we can set the prefix of the CSS classes we add for the animation.
Between the style
tags, we have the styles for various stages of the animation.
The stages of the transitions are listed at https://v3.vuejs.org/guide/transitions-overview.html#class-based-animations-transitions.
Conclusion
We can add in-component guards and route transitions with Vue Router 4.
The way we add route transitions is different from Vue Router 3.