iniubong Obonguko
The Growing Dev.

The Growing Dev.

How to Create Beautiful Page Transitions with Vue Router 4

How to Create Beautiful Page Transitions with Vue Router 4

iniubong Obonguko's photo
iniubong Obonguko
·Aug 11, 2021·

5 min read

Subscribe to my newsletter and never miss my upcoming articles

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 🤗

 
Share this