Introduction
Vue Router is a one-stop shop for all your page routing needs whenever you develop a Single Page Application (S.P.A) with the Vue js framework.
It makes it easier to add features such as page redirects, transitions, dynamic routing, etc, etc.. all in a bid to improve the user experince of your application.
Today, we'll learn how to utilize one of its many features which is being able to add page transitions and animations to our applications.
Prerequisites
This tutorial assumes that the reader has the following:
- Basic knowledge of how Vue works.
- Vue CLI installed on their machine.
Getting started
Let's setup a basic Vue application which we'll use as a base for our tutorial.
vue create router-transition
you'll see a prompt to pick a preset. Choose the default Vue 3 preset to get up and running.
cd router-transition && yarn add vue-router@4
//main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App';
import PageOne from './components/PageOne';
import PageTwo from './components/PageTwo';
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: '/pageone', component: PageOne },
{ path: '/pagetwo', component: PageTwo }
]
});
createApp(App).use(router).mount('#app')
<!-- App.Vue -->
<template>
<div id="app">
<div class="nav">
<router-link to="/pageone">Page One</router-link> |
<router-link to="/pagetwo">page Two</router-link>
</div>
<router-view></router-view>
</div>
</template>
<script>
export default { name: 'App' }
</script>
<!-- PageOne.vue-->
<template>
<div>Welcome to Page One!</div>
</template>
<script>
export default { name: 'PageOne' }
</script>
<!-- PageTwo -->
<template>
<div>Welcome to Page Two!</div>
</template>
<script>
export default { name: 'PageTwo' }
</script>
Route Transitions
Vue Router makes it super simple to setup our application to include transitions as our user moves between the various pages in our application.
N.B: The syntax on how to implement this in Vue Router V4 is quite different from the old V3 syntax .
Vue Router provides us with the transition
element tags to create page transitions with. The name
attribute is used to add transition classes to the page being moved to or from.
Vue Router provides us with six transition classes which can be prefixed with the value of the name
attribute. These classes are applied during the life cycle of the transition.
We also get access to the tansition mode
attribute on the transition
element. What this does is to prevent our pages from transitioning simultaneously which is somewhat unpleasant for our user experience.
There are two transition modes that Vue Router provides us with;
in-out
: New element transitions in first, then when complete, the current element transitions out.out-in
: Current element transitions out first, then when complete, the new element transitions in.
With all that having being said, let's take a look at how we can apply all that to our code;
<!-- App.Vue -->
<template>
<div>
<div class="nav">
<router-link to="/pageone">Page One</router-link> |
<router-link to="/pagetwo">Page Two</router-link>
</div>
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<component :is="Component" :key="$route.path" />
</transition>
</router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .4s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
From the code block above, we can see that for this to work, we have to wrap the transition
element between the router-view
element and assign a v-slot
directive to the router-view
element with its argument being the current component being rendered.
Next, on the transition
element, we've added the transition mode of out-in
and assigned the value of "fade" to the name
attribute. We'll use this to create CSS classes to style the pages being transitioned to or from.
Then, we wrap Vue's custom component
element in-between the transition
element tags and set its is
attribute to the current component being rendered and also a key
attribute equal to the current path dynamically in the form of $route.path
. This is to ensure routes are rendered correctly as intended.
Last, to make all this functional we added CSS styling for the different transition life cycles we have chosen to target. We only used the CSS transition and opacity properties here, but feel free to tweak this and play around with the values of the existing CSS attributes and try out other fun ones.
Per-route transitions
Vue Router lets us assign custom transitions per component route visited.
To do this, we'll make use of the meta
field property on each of our defined route.
We can then define our CSS styles to make the transitions work in each of the components.
//main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App';
import PageOne from './components/PageOne';
import PageTwo from './components/PageTwo';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/pageone',
component: PageOne,
meta: { transition: 'fade' },
},
{
path: '/pagetwo',
component: PageTwo,
meta: { transition: 'slide-in' },
}
]
})
createApp(App).use(router).mount('#app')
Let's look at an example of how to use this in our component;
<!-- PageOne.Vue -->
<router-view v-slot="{ Component, route }">
<!-- Use any custom transition and fallback to `fade` -->
<transition :name="route.meta.transition || 'fade'">
<component :is="Component" />
</transition>
</router-view>
Here, we assign the value of the name
attribute dynamically from the value of the transition
property in our meta field and a dd a fall-back value in case the transition we defined for that component route has issues.
Conclusion
We've learnt how to create route transitions using the version 4 of the Vue Router Package.
Do you have any questions or suggestions? Please leave them in the comment section below. Cheers ๐ค