Tutorial

Getting Started with Component Transitions in Vue

JavaScriptVue.js

While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

When we build applications, we aim to make them intuitive for users. We want our users to have a smooth experience using it, and to feel our application flowing from one point to another, rather than just jump between screens.

If we switch components without transitions, we see a sharp change every time a new component is called up. This is not ideal and can result in our users having a poor experience with our application.

In this tutorial, you will learn how to improve the flow of your application by using component transitions in Vue.

Prerequisites

  1. Vue CLI 3 for installing Vue
  2. Knowledge of JavaScript
  3. Knowledge of Vue.js

Setup Our Application

To begin, create a Vue application. Run the following command:

  • vue create component-transitions
  • cd component-transitions

Once you are done creating the application, you need to define a component you will use for the transitions.

Update The App Component
When we create a new Vue application, the CLI creates an App.vue file inside the ./src directory. Open the file and update the style section as follows:

[...]
<style>
    [...] 
    h3 {
        margin: 40px 0 0;
    }
    ul {
        list-style-type: none;
        padding: 0;
    }
    li {
        display: inline-block;
        margin: 0 10px;
    }
    a {
        color: #42b983;
    }
</style>

We created global styles we wish to share across all our components. This way, you will not have to add styles per component again.

Update The HelloWorld Component
Our Vue application also comes with a HelloWorld.vue file in located in ./src/components directory. Open the file and edit as follows:

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'HelloWorld',
        props: {
            msg: String
        }
    }
</script>

Create The About Component
We are going to create a new component About.vue inside the ./src/components directory. Open the file and add the following:

<template>
    <div>
        <h1>{{ msg }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'About',
        props: {
            msg: String
        }
    }
</script>

Create Another Component
We are going to create another component Extra.vue inside the ./src/components directory. Open the file and add the following:

<template>
    <div>
        <h1>{{ intro }}</h1>
    </div>
</template>

<script>
    export default {
        name: 'Extra',
        props: {
            msg: String
        },
        data(){
            return {
                intro : "Extra"
            }
        },
        watch: {
            msg : {
                immediate: true, 
                handler(val, oldval) {
                    //
                }
            }
        }
    }
</script>

For our extra component, we have added a watch method to track the updates to the msg prop. When the message prop updates, we want to update the intro property.

We defined it this way to allow us to use transitions on the component.

Rendering Our Components

Vue provides a variety of ways to apply transition effects when items in a component are updated or when components themselves are changed. It ranges from applying CSS classes for transitions and animations to using 3rd party JavaScript libraries for transition effects.

The first set of transitions you will define will be on change of components. You will use conditional rendering to display the components we created and apply transition as they render.

Import The Components
We need to import the components we created into our App.vue component. Open the file and edit as follows:

[...]
<script>
    import HelloWorld from './components/HelloWorld.vue'
    import About from './components/About.vue'
    import Extra from './components/Extra.vue'

    export default {
        name: 'app',
        components: {
            HelloWorld, About, Extra
        }
    }
</script>

Use The Components
Now that we have imported the components, let us use it in our App component. Edit the App.vue file as follows:

<template>
    <div id="app">
        <img src="./assets/logo.png">
        <HelloWorld msg="Welcome to your Vue.js application"/>
        <Extra :msg="extra"/>
        <About msg="This is the About page"/>
        <button @click="changeExtra">Update Extra</button>
    </div>
</template>

We defined a function changeExtra to listen for button clicks and also bound the msg prop for the Extra component to extra attribute. Now, let’s create the extra attribute and changeExtra method. You will just leave the Vue.js logo there so the page doesn’t feel empty ?

Edit the file as follows:

[...]
export default {
    name: 'app',
    components: {
        HelloWorld, About, Extra
    },
    data(){
        return {
            extra : "Extra"
        }
    },
    methods : {
        changeExtra(){
            this.extra = "This is extra"
        }
    },
}
[...]

Define Links For Switching Components
We are going to show one component at a time. To do this, you will have a set of links that would allow us to state which component to use at a certain time.

Open the App.vue file and add the following:

<template>
    <div id="app">
        [...]
        <div>
            <ul>
                <li @click="showHome">Home</li>
                <li @click="showAbout">About</li>
                <li @click="showExtra">Extra</li>
            </ul>
        </div>
    </div>
</template>

Then add the methods we used above:

[...]
methods : {
    [...]
    showHome(){
        this.displayHome = true
        this.displayAbout = false
        this.displayExtra = false
    },
    showAbout(){
        this.displayHome = false
        this.displayAbout = true
        this.displayExtra = false
    },
    showExtra(){
        this.displayHome = false
        this.displayAbout = false
        this.displayExtra = true
    }
},
[...]

Finally, we define the properties — displayHome, displayAbout, displayExtra.

[...]
data(){
    return {
        extra : "Extra",
        displayHome : true,
        displayAbout : false,
        displayExtra : false
    }
},
[...]

We set displayHome to true so that anytime we load our application, it shows up first. The rest is false so they do not show up.

Conditional Rendering Of Our Components
Now that we have defined links for showing our components, let’s render them based on certain conditions.
Still in the App.vue file, edit it as follows:

<template>
    <div id="app">
        <img src="./assets/logo.png">
        <HelloWorld msg="Welcome to your Vue.js application" v-if="displayHome"/>
        <About msg="This is the About page" v-if="displayAbout"/>
        <div v-if="displayExtra">
            <Extra :msg="extra"/>
            <button @click="changeExtra">Update Extra</button>
        </div>
        [...]
    </div>
</template>

So, we have completely rendered all of our components, now we can add transitions to it.

Defining Transitions On Data Change

You will modify Extra component. We want to add a transition effect when we update the data inside of it. Open the Extra.vue file in the ./src/components/ directory and edit as follows:

<template>
    <div>
        <transition name="fade">
            <h1 v-if="!msg">{{ intro }}</h1>
        </transition>
        <transition name="fade">
            <h1 v-if="msg">{{ msg }}</h1>
        </transition>
    </div>
</template>
[...]
<style scoped>
   .fade-enter-active{
        transition: opacity 1.5s;
    }
    .fade-leave-active {
        opacity: 0;
    }
    .fade-enter, .fade-leave-to {
        opacity: 0;
    }
</style>

When you click the Update Extra button, you will notice a slide fading transition occur. The transition is noticeable, so our users will likely see it.

We are able to achieve the transition by wrapping our element in a Vue transition element and then defining the effect we want the transition element to use. In our case, we used opacity to make the component appear and disappear.

Note: For data change transitions, you might want to use state transition as it provides a more robust experience. Read more about State Transitions.

Vue provides hooks at different stages of the transition cycle that we can hook into and define how we want the transition to be. I’ve added an image below from Vue.js website to illustrate this:

Vue Transition Diagram

v represents the name of our transition. In the case of the Extra component, we replace v with fade to have fade-enter in place of v-enter and so on.

Defining Transitions On Component Change

Define Transition On The HelloWorld Component
Now, to the App component where you will explore different other ways to implement transitions. Let’s define the transition on the HelloWorld component. Open the App.vue file and edit as follows:

<transition name="welcome">
    <HelloWorld msg="Welcome to your Vue.js application" v-if="displayHome"/>
</transition>

Our transition will be named “welcome”. Now, add the transition classes to get your desired effect:

<style scoped>
    /* Welcome Styles */
    .welcome-enter {
        transform: translateX(10px);
        opacity: 0;
    }
    .welcome-enter-active {
        transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    }
    .welcome-leave-active, .welcome-leave-to {
        opacity: 0;
    }
</style>

Now, every time we click the Home link, there will be a little shaking ? as our component shows.

We also created a new style element and added ‘scoped` to it.

Define Transition On The About Component
You will take a similar step with what we did for the HelloWorld component. Open the file and add the following:

[...]
<transition name="about">
    <About msg="This is the About page" v-if="displayAbout"/>
</transition>
[...]

Then add the transition effect:

<style scoped>
    [...]
    /* About Styles */
    .about-enter {
        width: 30%;
        opacity: 0;
    }
    .about-enter-active {
        transition: all 2s ease-in-out;
    }
    .about-leave-active, .about-leave-to {
        opacity: 0;
    }
    .about-enter-to {
        width:100%;
        opacity: 1;
        margin-left: auto;
    }
</style>

Define The Transition On Extra Component
Finally, let’s also add a transition for enter and exit of the extra component:

[...]
<transition name="extra">
    <div v-if="displayExtra">
        <Extra :msg="extra"/>
        <button @click="changeExtra">Update Extra</button>
    </div>
</transition>
[...]

Then add the styles for the transition:

<style scoped>
    [...]
    /* Extra Styes */
    .extra-enter {
        transform: translateX(-200px);
        opacity: 0;
    }
    .extra-enter-to {
        transform: translateX(0px);
    }
    .extra-enter-active {
        transition: all 1s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    }
    .extra-leave-active, .extra-leave-to {
        opacity: 0;
    }
</style>

And that’s it for component transitions.

Run The Application

Now that we are done defining transitions for our various components, let’s run the application and see what it looks like.

From your terminal, run the following command:

  • npm run serve

Then visit the application on the url that appears.

Conclusion

We have looked at vue component transitions in this tutorial. We learned how to add transitions to our application, although you may want to use fewer such transitions in a real application.

Try to use different CSS transitions for your components and see what you can come up with.

0 Comments

Creative Commons License