Categories
Vue 3

Vue 3 — JavaScript Transitions

Spread the love

Vue 3 is in beta and it’s subject to change.

Vue 3 is the up and coming version of Vue front end framework.

It builds on the popularity and ease of use of Vue 2.

In this article, we’ll look at setting transition durations and creating JavaScript transitions.

Transition Durations

We can set transition durations with the duration prop.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .bounce-enter-active {
        animation: bounce-in 1.5s;
      }
      .bounce-leave-active {
        animation: bounce-in 1.5s reverse;
      }
      @keyframes bounce-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.5);
        }
        100% {
          transform: scale(1);
        }
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle
      </button>

      <transition name="bounce" :duration="1000">
        <p v-if="show">hello</p>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            show: false
          };
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We just add the duration prop to the transition component to set the duration.

The duration is in milliseconds.

We can also set separate values for enter and leave transitions:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      .bounce-enter-active {
        animation: bounce-in 1.5s;
      }
      .bounce-leave-active {
        animation: bounce-in 1.5s reverse;
      }
      [@keyframes](http://twitter.com/keyframes "Twitter profile for @keyframes") bounce-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.5);
        }
        100% {
          transform: scale(1);
        }
      }
    </style>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle
      </button>

      <transition name="bounce" :duration="{ enter: 500, leave: 1000 }">
        <p v-if="show">hello</p>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            show: false
          };
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

We have the enter and leave properties again in milliseconds to set the duration of each effect.

JavaScript Hooks

There’re JavaScript hooks for each stage of a transition.

They include:

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

css set to false means we use JavaScript to apply the transition effects.

And the hooks are in the methods property of the component as usual.

The signatures of the are:

methods: {
  beforeEnter(el) {
    // ...
  },

  enter(el, done) {
    // ...
    done()
  },

  afterEnter(el) {
    // ...
  },

  enterCancelled(el) {
    // ...
  },

  beforeLeave(el) {
    // ...
  },

  leave(el, done) {
    // ...
    done()
  },

  afterLeave(el) {
    // ...
  },

  leaveCancelled(el) {
    // ...
  }
}

el is the element and done is a function to indicate that the transition is done.

We can use the Greensock library to make JavaScript transitions.

For instance, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script>
  </head>
  <body>
    <div id="app">
      <button @click="show = !show">
        Toggle
      </button>

      <transition
        @before-enter="beforeEnter"
        @enter="enter"
        @leave="leave"
        :css="false"
      >
        <p v-if="show">
          hello world
        </p>
      </transition>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            show: false
          };
        },
        methods: {
          beforeEnter(el) {
            gsap.set(el, {
              scaleX: 0.9,
              scaleY: 1.6
            });
          },
          enter(el, done) {
            gsap.to(el, {
              duration: 1,
              scaleX: 1.2,
              scaleY: 0.9,
              opacity: 1,
              x: 150,
              ease: "elastic.inOut(2.8, 1)",
              onComplete: done
            });
          },
          leave(el, done) {
            gsap.to(el, {
              duration: 0.5,
              scaleX: 1,
              scaleY: 1,
              x: 300,
              ease: "elastic.inOut(2.5, 1)"
            });
            gsap.to(el, {
              duration: 0.2,
              delay: 0.5,
              opacity: 0,
              onComplete: done
            });
          }
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>

to create our animation with Greensock.

We added Greensock library with a script tag.

Then we call the gsap.set method to set the initial scale of our element before we start the animation.

The enter method has our enter transition effect.

The duration is set to 1 for 1 second

scaleX and scaleY change the sizing of our p element.

opacity changes the opacity.

x is the translation distance to the right in pixels.

ease is the easing effect.

onComplete is a callback which we indicate that the transition is done.

We have similar things in the leave method.

We have 2 transition effects instead of one for the leave transition effect.

The methods are set as the values of the corresponding directives in the transition component so we can use it.

Conclusion

We can use JavaScript to create our transitions instead of CSS.

A library like Greensock makes this an easy process.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *