Tutorial

Getting Started with Component Transitions in Vue

JavaScriptVue.js
This tutorial is out of date and no longer maintained.

Introduction

Smooth transitions offer a less jarring user experience when adding or removing elements in an application. Finding sensible opportunities to add transitions to your project has the potential to assist users with navigating through your application and processing information presented to them.

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

Prerequisites

If you would like to follow along with this article, you will need:

  • Familiarity with Vue components and props.

Setting Up the Project

You can use @vue/cli to create a new Vue.js Project.

In your terminal window, use the following command:

  • vue create --default vue-transition-example

This will use the default configurations for creating a Vue.js Project.

Navigate to the newly created project directory:

  • cd vue-transition-example

Start the project to verify that there are no errors.

  • npm run serve

If you visit the local app (typically at localhost:8080) in your web browser, you will see a "Welcome to Your Vue.js App" message.

With this scaffolding set in place, you can begin work on the components you will apply transitions to.

@vue/cli creates an App.vue file inside the src directory.

Open the App.vue file with your code editor and update the <style> section:

src/App.vue
[...]
<style>
[...]
ul {
    list-style-type: none;
    padding: 0;
}

li {
    display: inline-block;
    margin: 0 10px;
}

a {
    color: #42b983;
}
</style>

This code will provide global styles that will be shared by all components. This way, you will not have to add styles per component again.

@vue/cli also creates a HelloWorld.vue file in located in ./src/components directory.

This tutorial will remove the component-specific styles to rely solely upon the styles in App.vue.

Open the HelloWorld.vue file with your code editor and change the contents of the <style> section:

src/components/HelloWorld.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

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

<style scoped>

</style>

Next, use your code editor to create a new About.vue file in the src/components directory:

src/components/About.vue
<template>
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>

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

Then, use your code editor to create a new Extra.vue file in the src/components directory:

src/components/Extra.vue
<template>
  <div>
    <h1>{{ intro }}</h1>
  </div>
</template>

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

<style scoped>

</style>

The Extra component contains a watch method to track the updates to the msg prop. When the msg prop updates, the intro property is updated.

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 third-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.

You will need to import the components you created into your App.vue component.

Open the App.vue file with your code editor and add the About and Extra components:

[...]
<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>

While still in the App.vue file, add the following lines to the <template> section:

src/App.vue
<template>
  <div id="app">
    <HelloWorld
      msg="Welcome to Your Vue.js App"
    />
    <About
      msg="This is the About message"
    />
    <Extra
      :msg="extra"
    />
    <button @click="changeExtra">Update Extra</button>
  </div>
</template>

This code references thechangeExtra function that will listen for button clicks. It also bound the message prop for the Extra component to extra attribute.

While still in the App.vue file, add the following lines to the <script> section:

src/App.vue
<script>
[...]
export default {
  name: 'App',
  components: {
    HelloWorld,
    About,
    Extra
  },
  data() {
    return {
      extra: 'This is the Extra message'
    }
  },
  methods: {
    changeExtra() {
      this.extra = 'This is the updated Extra message'
    }
  }
}
</script>

This application will toggle between HellowWorld, About, and Extra components. To achieve this, you will have a set of links that would allow you to state which component to use at a certain time.

While still in the App.vue file, add the following lines to the <template> section:

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

While still in the App.vue file, add the showHome, showAbout, and showExtra methods to the <script> section:

src/App.vue
<script>
[...]
export default {
  name: 'App',
  components: {
    HelloWorld,
    About,
    Extra
  },
  data() {
    return {
      extra: 'This is the Extra message',
      displayHome: true,
      displayAbout: false,
      displayExtra: false
    }
  },
  methods: {
    changeExtra() {
      this.extra = 'This is the updated Extra message'
    },
    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
    }
  }
}
</script>

This code sets displayHome to true so that the HelloWorld component will display intitialy. displayAbout and displayextra are set to false so they do not display initially.

Now that you have defined buttons for toggling the display of your components, you can use v-if to conditionally display components.

While still in the App.vue file, addv-if to the <template> section:

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

At this point, you can save your changes and view the application in your web browser to ensure that everything up to this point is functioning as expected.

Your application will consist of three buttons: Home, About, and Extra. It will initially be displaying the HelloWorld component’s message of “Welcome to Your Vue.js App”. Clicking the About button will display the About component’s message of “This is the About message”. Clicking the Extra button will display the Extra component’s message of “This is the Extra message”. Clicking on the Update Extra button will change this message to “This is the updated Extra message”.

Defining Transitions on Data Change

Now, you will modify Extra component to add a transition effect when the message is changed.

Open the Extra.vue file in your code editor and add the <transition> element to the <template> section:

src/components/Extra.vue
<template>
  <div>
    <transition name="fade">
      <h1 v-if="!msg">{{ intro }}</h1>
    </transition>
    <transition name="fade">
      <h1 v-if="msg">{{ msg }}</h1>
    </transition>
  </div>
</template>

While still in the Extra.vue file, add the following lines to the <style> section:

src/components/Extra.vue
<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 slight fading transition occur. The transition is noticeable, so users will likely see it.

You are able to achieve the transition by wrapping the element in a Vue transition element and then defining the effect you want the transition element to use. In this case, you 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 you can hook into and define how you want the transition to be. The Extra component uses fade-enter, fade-enter-active, fade-leave-active, and fade-leave-to.

Defining Transitions on Component Change

In this section, you will modify the App component to apply transitions for HelloWorld, About, and Extra.

Open the App.vue file in your code editor and add the <transition> element to the <template> section around the HelloWorld component:

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

While still in the App.vue file, add the following lines to the <style> section:

src/App.vue
<style>
  [...]

  .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>

While still in the App.vue file, add the <transition> element to the <template> section around the About component:

src/App.vue
<transition name="about">
  <About
    msg="This is the About page"
    v-if="displayAbout"
  />
</transition>

While still in the App.vue file, add the following lines to the <style> section:

src/App.vue
<style>
  [...]

  .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>

While still in the App.vue file, add the <transition> element to the <template> section around the Extra component:

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

While still in the App.vue file, add the following lines to the <style> section:

src/App.vue
<style>
  [...]

  .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>

Now that you have completed defining transitions for the various components, let’s run the application.

From your terminal, run the following command:

  • npm run serve

Then visit the application with your web browser. Interact with the various buttons and observe how the transitions behave.

Conclusion

In this tutorial, you learned how to improve the flow of your application by using component transitions in Vue. Continue your learning by trying different CSS transitions for your components.

If you’d like to learn more about Vue.js, check out our Vue.js topic page for exercises and programming projects.

Creative Commons License