Built-in Components

Provides animated transition effects to a single
element or component.

<Transition name="fade" mode="out-in" appear>
  <component :is="view"></component>
</Transition>

Vue provides us with the built-in component in cases where we want to animate an element as it is removed from, or added to, our application with v-if or v-show, because that would be hard to do with plain CSS animation.

The Six Classes

There are six classes automatically available to us when we use the component.

As an element inside the component is added, we can use these first three classes to animate that transition: v-enter-from v-enter-active v-enter-to

And as an element is removed inside the component, we can use the next three classes : v-leave-from v-leave-active v-leave-to

^Note: There can only be one element on root level of the component.

We can also use the v-enter-active and v-leave-active to set styling or animation during adding or during removal of an element:

<template>
  <h1>Add/Remove <p> Tag</h1>
  <button @click="this.exists = !this.exists">{{btnText}}</button><br>
  <Transition>
    <p v-if="exists">Hello World!</p>
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      exists: false
    }
  },
  computed: {
    btnText() {
      if(this.exists) {
        return 'Remove';
      }
      else {
        return 'Add';
      }
    }
  }
}
</script>

<style>
  .v-enter-active {
    background-color: lightgreen;
    animation: added 1s;
  }
  .v-leave-active {
    background-color: lightcoral;
    animation: added 1s reverse;
  }
  @keyframes added {
    from {
      opacity: 0;
      translate: -100px 0;
    }
    to {
      opacity: 1;
      translate: 0 0;
    }
  }
  p {
    display: inline-block;
    padding: 10px;
    border: dashed black 1px;
  }
</style>

The Transition ‘name’ Prop

<Transition name="swirl">

If the transition name prop value is set to ‘swirl’, the automatically available classes will now start with ‘swirl-’ instead of ‘v-’: swirl-enter-from swirl-enter-active swirl-enter-to swirl-leave-from swirl-leave-active swirl-leave-to

JavaScript Transition Hooks

Transition Class JavaScript Event v-enter-from before-enter v-enter-active enter v-enter-to after-enter enter-cancelled v-leave-from before-leave v-leave-active leave v-leave-to after-leave leave-cancelled (v-show only)

  <Transition @after-enter="onAfterEnter">
    <p v-show="pVisible" id="p1">Hello World!</p>
  </Transition>

The ‘appear’ Prop

If we have an element that we want to animate when the page loads, we need to use the appear prop on the component.

  <Transition appear>
    <p id="p1">Hello World!</p>
  </Transition>

mode=“out-in”

We use the mode=“out-in” prop and prop value on the component so that the removal of an element is finished before the next element is added.

<template>
  <h1>mode="out-in"</h1>
  <p>Click the button to get a new image.</p>
  <p>With mode="out-in", the next image is not added until the current image is removed. Another difference from the previous example, is that here we use computed prop instead of a method.</p>
  <button @click="indexNbr++">Next image</button><br>
  <Transition mode="out-in">
    <img src="/img_pizza.svg" v-if="imgActive === 'pizza'">
    <img src="/img_apple.svg" v-else-if="imgActive === 'apple'">
    <img src="/img_cake.svg" v-else-if="imgActive === 'cake'">
    <img src="/img_fish.svg" v-else-if="imgActive === 'fish'">
    <img src="/img_rice.svg" v-else-if="imgActive === 'rice'">
  </Transition>
</template>

<script>
export default {
  data() {
    return {
      imgs: ['pizza', 'apple', 'cake', 'fish', 'rice'],
      indexNbr: 0
    }
  },
  computed: {
    imgActive() {
      if(this.indexNbr >= this.imgs.length) {
        this.indexNbr = 0;
      }
      return this.imgs[this.indexNbr];
    }
  }
}
</script>

<style>
  .v-enter-active {
    animation: swirlAdded 0.7s;
  }
  .v-leave-active {
    animation: swirlAdded 0.7s reverse;
  }
  @keyframes swirlAdded {
    from {
      opacity: 0;
      rotate: 0;
      scale: 0.1;
    }
    to {
      opacity: 1;
      rotate: 360deg;
      scale: 1;
    }
  }
  img {
    width: 100px;
    margin: 20px;
  }
  img:hover {
    cursor: pointer;
  }
</style>