Lesson 05-Vue3 Animation Handling and Transition Effects

Vue 3 Transition System

Basic Concepts

Vue 3’s transition animations are primarily implemented using the <transition> and <transition-group> components. <transition> handles transitions for single elements or components, while <transition-group> manages transitions for lists, including adding, moving, and removing items.

Using the <transition> Component

The <transition> component accepts a name attribute to specify the prefix for CSS class names. Vue automatically applies specific classes to trigger transition effects.

<template>
  <transition name="fade">
    <p v-if="show">Hello World</p>
  </transition>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

Transition Classes

Vue automatically applies the following classes during transitions:

  • .NAME-enter-active and .NAME-leave-active: Applied throughout the transition phase.
  • .NAME-enter-from and .NAME-leave-to: Applied at the start of the transition.
  • .NAME-enter-to and .NAME-leave-from: Applied at the end of the transition.

Using the <transition-group> Component

For list transitions, <transition-group> is more suitable, handling additions, deletions, and reordering of list items.

<template>
  <transition-group name="list" tag="ul">
    <li v-for="item in items" :key="item.id">{{ item.text }}</li>
  </transition-group>
</template>

<style>
.list-move {
  transition: transform 1s;
}
</style>

Advanced Usage

  • CSS Animations: Beyond transitions, CSS animations can create more complex effects.
  • JavaScript-Driven Transitions: Use enter and leave hooks to control transitions with JavaScript.
  • Multi-Element Transitions: The appear attribute enables transitions for elements on initial render.
  • Custom Transition Classes: Use the css and mode attributes to customize transition classes and modes.
<template>
  <transition
    name="slide"
    mode="out-in"
    :css="false"
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter"
    @enter-cancelled="enterCancelled"
    @before-leave="beforeLeave"
    @leave="leave"
    @after-leave="afterLeave"
    @leave-cancelled="leaveCancelled"
  >
    <p v-if="show">Hello World</p>
  </transition>
</template>

<script>
export default {
  data() {
    return {
      show: true
    };
  },
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0;
      el.style.transform = 'translateX(30px)';
    },
    enter(el, done) {
      requestAnimationFrame(() => {
        el.style.opacity = 1;
        el.style.transform = 'translateX(0)';
        requestAnimationFrame(done);
      });
    },
    afterEnter(el) {},
    enterCancelled(el) {},
    beforeLeave(el) {},
    leave(el, done) {
      el.style.opacity = 0;
      el.style.transform = 'translateX(30px)';
      requestAnimationFrame(done);
    },
    afterLeave(el) {},
    leaveCancelled(el) {}
  }
};
</script>

Using Third-Party Animation Libraries

While Vue’s animation system is powerful, third-party animation libraries often provide richer functionality and better performance for complex animations. Vue 3 seamlessly integrates with libraries like GreenSock (GSAP), Anime.js, and Popmotion, enabling highly customized animation effects.

Importing Third-Party Animation Libraries

First, install the chosen animation library. For GSAP, use npm or yarn:

npm install gsap
# or
yarn add gsap

Using GSAP in Vue Components

Once installed, import GSAP into your Vue component to create animations.

// components/AnimatedBox.vue
import { gsap } from 'gsap';

export default {
  name: 'AnimatedBox',
  data() {
    return {
      isAnimated: false
    };
  },
  methods: {
    animateBox() {
      this.isAnimated = true;
      gsap.to(this.$el, {
        duration: 1,
        backgroundColor: 'red',
        height: '100px',
        width: '100px',
        onComplete: () => {
          this.isAnimated = false;
        }
      });
    }
  }
};

Add a button to trigger the animation in the template:

<template>
  <div class="box" :class="{ animated: isAnimated }" @click="animateBox"></div>
</template>

<style scoped>
.box {
  width: 50px;
  height: 50px;
  background-color: blue;
  cursor: pointer;
}

.animated {
  /* Add transition effects here if needed */
}
</style>

Combining with Vue 3’s <transition> Component

Vue 3’s <transition> component can be combined with GSAP for more complex animations.

<template>
  <transition name="fade">
    <div v-if="isVisible" class="box" @click="toggleVisibility"></div>
  </transition>
</template>

<script>
import { gsap } from 'gsap';

export default {
  data() {
    return {
      isVisible: false
    };
  },
  methods: {
    toggleVisibility() {
      this.isVisible = !this.isVisible;
      if (this.isVisible) {
        gsap.from('.box', { duration: 1, opacity: 0, scale: 0.5 });
      } else {
        gsap.to('.box', { duration: 1, opacity: 0, scale: 0.5, onComplete: () => (this.isVisible = false) });
      }
    }
  }
};
</script>

<style scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

Using Anime.js

Anime.js, a lightweight animation library, integrates easily with Vue 3.

// components/AnimeCircle.vue
import anime from 'animejs';

export default {
  name: 'AnimeCircle',
  data() {
    return {
      animation: null
    };
  },
  mounted() {
    this.animation = anime({
      targets: this.$el,
      r: 100,
      duration: 2000,
      easing: 'easeInOutSine',
      loop: true
    });
  },
  beforeDestroy() {
    this.animation.pause();
  }
};

Create a circular element in the template:

<template>
  <div class="circle"></div>
</template>

<style scoped>
.circle {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: red;
}
</style>

Code Analysis

  • Vue 3 Transition System: <transition> and <transition-group> provide a robust framework for animating single elements and lists, with customizable CSS and JavaScript-driven transitions.
  • Third-Party Libraries: GSAP and Anime.js enhance Vue’s capabilities, offering advanced animation control for complex effects.
  • Integration: Combining Vue’s transition system with third-party libraries allows for seamless, high-performance animations.
  • Best Practices: Use CSS for simple transitions, JavaScript hooks for precise control, and third-party libraries for sophisticated animations, ensuring cleanup in lifecycle hooks to prevent memory leaks.

Share your love