YouTip LogoYouTip

Vue Transitions

Vue.js Transitions & Animations

In this chapter, we will primarily discuss Vue.js transition effects and animation effects.

Transitions

Vue provides multiple ways to apply transition effects when inserting, updating, or removing DOM elements.

Vue offers a built-in transition wrapper component, which is used to wrap the component that needs to implement transition effects.

Syntax Format

<transition name = "nameoftransition">
   <div></div>
</transition>

We can understand how Vue transitions work through the following example:

Example

<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition name = "fade">
    <p v-show = "show" v-bind:style = "styleobj">Animation Example</p>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#databinding',
    data: {
        show:true,
        styleobj :{
            fontSize:'30px',
            color:'red'
        }
    },
    methods : {
    }
});
</script>

Try it yourself Β»

In this example, clicking the "Click Me" button toggles the value of the variable show from true to false. If it is true, the content of the child element p tag is displayed.

The following code shows the transition tag wrapping the p tag:

<transition name = "fade">
    <p v-show = "show" v-bind:style = "styleobj">Animation Example</p>
</transition>

A transition is essentially a fade-in and fade-out effect. Vue provides 6 classes to toggle during the transition of an element's display and hide:

  • v-enter: Defines the starting state of the entering transition. It takes effect before the element is inserted and is removed in the next frame after the element is inserted.
  • v-enter-active: Defines the active state of the entering transition. It applies throughout the entire entering transition phase, takes effect before the element is inserted, and is removed after the transition/animation completes. This class can be used to define the duration, delay, and easing function of the entering transition.
  • v-enter-to: (Version 2.1.8+) Defines the ending state of the entering transition. It takes effect in the next frame after the element is inserted (at the same time v-enter is removed) and is removed after the transition/animation completes.
  • v-leave: Defines the starting state of the leaving transition. It takes effect immediately when the leaving transition is triggered and is removed in the next frame.
  • v-leave-active: Defines the active state of the leaving transition. It applies throughout the entire leaving transition phase, takes effect immediately when the leaving transition is triggered, and is removed after the transition/animation completes. This class can be used to define the duration, delay, and easing function of the leaving transition.
  • v-leave-to: (Version 2.1.8+) Defines the ending state of the leaving transition. It takes effect in the next frame after the leaving transition is triggered (at the same time v-leave is removed) and is removed after the transition/animation completes.

For these class names that toggle during the transition, if you use a <transition> without a name, v- is the default prefix for these class names. If you use <transition name="my-transition">, then v-enter will be replaced with my-transition-enter.

v-enter-active and v-leave-active can control the different easing curves for the entering/leaving transitions, as shown in the example in the following section.

CSS Transitions

Usually, we use CSS transitions to achieve effects.

Example:

<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition name="slide-fade">
    <p v-if="show">hello</p>
</transition>
</div>
<script type = "text/javascript">
new Vue({
    el: '#databinding',
    data: {
        show: true
    }
})
</script>

Try it yourself Β»

CSS Animations

CSS animations are used similarly to CSS transitions, but in animations, the v-enter class name is not immediately removed after the node is inserted into the DOM, but is removed when the animationend event is triggered.

Example:

<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition name="bounce">
    <p v-if="show"> -- Learning is not just about technology, but also about dreams!!!</p>
</transition>
</div>
<script type = "text/javascript">
new Vue({
    el: '#databinding',
    data: {
        show: true
    }
})
</script>

Try it yourself Β»

Custom Transition Class Names

We can customize transition class names using the following attributes:

  • enter-class
  • enter-active-class
  • enter-to-class (2.1.8+)
  • leave-class
  • leave-active-class
  • leave-to-class (2.1.8+)

Custom transition class names have higher priority than regular class names, allowing for better integration with third-party animation libraries like animate.css.

Example:

<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition
    name="custom-classes-transition"
    enter-active-class="animated tada"
    leave-active-class="animated bounceOutRight"
>
    <p v-if="show"> -- Learning is not just about technology, but also about dreams!!!</p>
</transition>
</div>
<script type = "text/javascript">
new Vue({
    el: '#databinding',
    data: {
        show: true
    }
})
</script>

Try it yourself Β»

Using Both Transitions and Animations

Vue must set up corresponding event listeners to know when a transition is complete. It can be transitionend or animationend, depending on the CSS rules applied to the element. If you use either one, Vue can automatically detect the type and set up the listener.

However, in some scenarios, you need to set both transition and animation effects on the same element. For example, the animation might be triggered and completed quickly, while the transition effect hasn't ended yet. In this case, you need to use the type attribute and set it to animation or transition to explicitly declare which type Vue should listen for.

Explicit Transition Duration

In many cases, Vue can automatically determine when the transition effect is complete. By default, Vue waits for the first transitionend or animationend event on the root element of the transition effect. However, this can be overriddenβ€”for example, we might have a carefully orchestrated series of transitions where some nested internal elements have delayed or longer transitions compared to the root element of the transition effect.

In such cases, you can customize an explicit transition duration (in milliseconds) using the duration attribute on the <transition> component:

<transition :duration="1000">...</transition>

You can also customize the entering and leaving durations separately:

<transition :duration="{ enter: 500, leave: 800 }">...</transition>

JavaScript Hooks

You can declare JavaScript hooks in the attributes:

HTML code:

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"
 
  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

JavaScript code:

// ...
methods: {
  // --------
  // Entering
  // --------
 
  beforeEnter: function (el) {
    // ...
  },
  // This callback is optional
  // Used in conjunction with CSS
  enter: function (el, done) {
    // ...
    done()
  },
  afterEnter: function (el) {
    // ...
  },
  enterCancelled: function (el) {
    // ...
  },
 
  // --------
  // Leaving
  // --------
 
  beforeLeave: function (el) {
    // ...
  },
  // This callback is optional
  // Used in conjunction with CSS
  leave: function (el, done) {
    // ...
    done()
  },
  afterLeave: function (el) {
    // ...
  },
  // leaveCancelled only used with v-show
  leaveCancelled: function (el) {
    // ...
  }
}

These hook functions can be used in conjunction with CSS transitions/animations or independently.

When using only JavaScript transitions, you must use done as a callback in enter and leave. Otherwise, they will be called synchronously, and the transition will complete immediately.

It is recommended to add v-bind:css="false" for elements that use only JavaScript transitions. This tells Vue to skip CSS detection and also avoids the influence of CSS during the transition.

A simple example using Velocity.js:

<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition
    v-on:before-enter="beforeEnter"
    v-on:enter="enter"
    v-on:leave="leave"
    v-bind:css="false"
  >
    <p v-if="show"> -- Learning is not just about technology, but also about dreams!!!</p>
</transition>
</div>
<script type = "text/javascript">
new Vue({
  el: '#databinding',
  data: {
    show: false
  },
  methods: {
    beforeEnter: function (el) {
      el.style.opacity = 0
      el.style.transformOrigin = 'left'
    },
    enter: function (el, done) {
      Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
      Velocity(el, { fontSize: '1em' }, { complete: done })
    },
    leave: function (el, done) {
      Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
      Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
      Velocity(el, {
        rotateZ: '45deg',
        translateY: '30px',
        translateX: '30px',
        opacity: 0
      }, { complete: done })
    }
  }
})
</script>

Try it yourself Β»

Initial Render Transition

You can set the transition for the initial render of a node using the appear attribute:

<transition appear>
  <!-- ... -->
</transition>

By default, this is the same as the entering/leaving transition, and you can also customize the CSS class names.

<transition
  appear
  appear-class="custom-appear-class"
  appear-to-class="custom-appear-to-class" (2.1.8+)
  appear-active-class="custom-appear-active-class"
>
  <!-- ... -->
</transition>

Custom JavaScript hooks:

<transition
  appear
  v-on:before-appear="customBeforeAppearHook"
  v-on:appear="customAppearHook"
  v-on:after-appear="customAfterAppearHook"
  v-on:appear-cancelled="customAppearCancelledHook"
>
  <!-- ... -->
</transition>

Transitions for Multiple Elements

We can set transitions for multiple elements, typically for lists and descriptions:

Note that when switching between elements with the same tag name, you need to set a unique value via the key attribute to mark them so that Vue can distinguish them. Otherwise, for efficiency, Vue will only replace the content inside the same tag.

<transition>
  <table v-if="items.length > 0">
    <!-- ... -->
  </table>
  <p v-else>Sorry, no content found.</p>
</transition>

Example:

<transition>
  <button v-if="isEditing" key="save">
    Save
  </button>
  <button v-else key="edit">
    Edit
  </button>
</transition>

In some scenarios, you can also use different states for the key attribute of the same element instead of v-if and v-else. The above example can be rewritten as:

<transition>
  <button v-bind:key="isEditing">
    {{ isEditing ? 'Save' : 'Edit' }}
  </button>
</transition>

Transitions for multiple elements using multiple v-if can be rewritten as a single element transition with dynamic attributes. For example:

<transition>
  <button v-if="docState === 'saved'" key="saved">
    Edit
  </button>
  <button v-if="docState === 'edited'" key="edited">
    Save
  </button>
  <button v-if="docState === 'editing'" key="editing">
    Cancel
  </button>
</transition>

Can be rewritten as:

<transition>
  <button v-bind:key="docState">
    {{ buttonMessage }}
  </button>
</transition>
// ...
computed: {
  buttonMessage: function () {
    switch (this.docState) {
      case 'saved': return 'Edit'
      case 'edited': return 'Save'
      case 'editing': return 'Cancel'
    }
  }
}
← Python3 Func ZipBootstrap4 Forms Custom β†’