DEV Community

Cover image for JavaScript and Vue animations
Brian Neville-O'Neill for LogRocket

Posted on • Originally published at blog.logrocket.com on

JavaScript and Vue animations

Written by David Atanda✏️

In a previous article, we covered Vue transitions and animations and how to create effects using transition classes with nothing more than CSS and the transition tag. Interestingly, you can do so much more with JavaScript by using it alone or combining it with CSS.

The transition tag ships with something called event hooks, which allow JavaScript to affect transitions. The event hooks affect the element just like the transition classes in CSS. With that, you can run JavaScript code at every stage of attachment or removal of the HTML element from the DOM as the animation or transition is taking place.

These hooks enable you to run JS code before the animation starts, while it’s in progress, and immediately after it’s done. This extra functionality can give you more control or flexibility with your UI, promote interaction, and improve the user experience.

The transition tag has default event hooks for JavaScript that attach themselves to methods, which have the actual code.

<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"

  @before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled"
> 
  [...]
</transition>
Enter fullscreen mode Exit fullscreen mode
  • @before-enter allows JavaScript code to run for one frame before it’s attached to the DOM
  • @enter emits the code that runs as it attaches to the DOM
  • after-enter emits the code that runs after it has been attached to the DOM
  • @enter-cancelled emits the code that clears the animation and aborts its playback (you can have other type of code there too)
  • @before-leave allows JavaScript code to run for one frame before it’s removed from the DOM
  • @leave emits the code that runs as it’s removed from the DOM
  • @after-leave emits the code that runs after it has been removed from the DOM
  • @leave-cancelled emits the code that runs if the animation is canceled

LogRocket Free Trial Banner

Let’s look at an example.

<template>
  <div>
    <div class="container">
    <button @click="display = !display">Switch</button>
    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"

      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled">
    <div class="item" v-if="display">1</div>
    </transition>
  </div>
  </div>
</template>
<style scoped>
  body {
    align-content: center;
  }
    .container {
        display: grid;
        grid-gap: 20px;
        width: 500px;
        margin: 0 auto;
      }
    .item {
      background-color: blue;
      height: 100px;
    }
    .fadeInClass {
      animation : fadeIn 1s;  
    }
    .fadeOutClass {
      animation : fadeOut 1s;  
    }
    @keyframes fadeIn {
      0% {
        opacity : 0
      }
      100% {
        opacity : 1;
      }
    }

    @keyframes fadeOut {
      0% {
        opacity : 1;
      }
      100% {
        opacity : 0;
      }
    }

</style>


<script>
export default {
  data () {
    return {
      display : false
    }
  },
  methods : {
    beforeEnter () {
      console.log("about to")
    },
    enter (el, done) {
       el.classList.add('fadeInClass');
      console.log("enter")
       done();
    },
    afterEnter (el) {
      el.addEventListener('animationend', () =>{el.classList.remove('fadeInClass'); } )
      console.log("after enter")
    },
    enterCancelled ()  {
     console.log("enter cancelled")
    },
    beforeLeave () {
      console.log("beforeLeave")
    },
    leave (el, done) {
      el.classList.add('fadeOutClass')
      console.log("leave")
       done();
    },
    afterLeave () {
      console.log("after-leave");
    },
     leaveCancelled ()  {
     console.log("leave cancelled")
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

The example above offers a use case of how to combine event hooks in JavaScript and CSS to create animations. In this case, we used @keyframes in CSS to create styles for both attaching and removing from the DOM. We then created the methods for our event hooks, where we added comments to the console and the styles to the element at each stage of attachment/removal with JavaScript.

Note: We added done() to only enter and leave because it helps the element in Vue to know when the transition/animation is done in JavaScript, because it’s not timed like it is with CSS.

Interestingly, you can also use any of the event hooks in isolation to run JavaScript code, so you don’t necessarily need to attach all the hooks to the transition tag for it to work. You can use only what you need.

For instance, you can simply add @after-leave to a transiton tag that’s already using CSS with the transition classes, and it’ll run whatever code you want after the animation has been removed from the DOM.

Here’s an example:

<template>
  <div>
    <div class="container">
    <button @click="display = !display">Switch</button>
    <transition  @after-leave="afterLeave" name="block">
    <div class="item" v-if="display" >1</div>
    </transition>
    <div id="comment"></div>
  </div>
  </div>
</template>
<style scoped>
  body {
    align-content: center;
  }
    .container {
        display: grid;
        grid-gap: 20px;
        width: 500px;
        margin: 0 auto;
      }
    .item {
      background-color: blue;
      height: 100px;
    }
    .block-enter {
    }
    .block-enter-active {
      animation : fadeIn 1s;
    }
    .block-leave {
    }
    .block-leave-active {
       animation : fadeOut 1s 
    }
      @keyframes fadeIn {
      0% {
        opacity : 0
      }
      100% {
        opacity : 1;
      }
    }

    @keyframes fadeOut {
      0% {
        opacity : 1;
      }
      100% {
        opacity : 0;
      }
    }
</style>


<script>
export default {
  data () {
    return {
      display : false
    }
  },
  methods : {

    afterLeave () {
      document.getElementById('comment').innerHTML = `The random number is ${(Math.random())}`
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

@after-leave is attached to the transition tag, which is already using transition classes for its operation. The @after-leave hook takes effect after the element has been removed from the DOM. It then runs the afterLeave() function and displays the statement about the random number. This can be reproduced with all the other event hooks we discussed about earlier.

If you’re using JavaScript hooks without any CSS at all, you can add :css="false" to your trasition tag. This tells the transition tag not to listen to any CSS because, which it typically does by default.

<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">
    <div class="item" v-if="display">1</div>
    </transition>
Enter fullscreen mode Exit fullscreen mode

Conclusion

With JavaScript, you can control elements completely through the DOM, depending on what you want to achieve within your project. You can always fit JavaScript at any point in your animations with the transition hooks, giving you the flexibility to precisely manipulate elements and create better and more scalable applications for your users.

To learn more, check out this crash course.


Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket.

Alt Text

LogRocket is like a DVR for web apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps - Start monitoring for free.


The post JavaScript and Vue animations appeared first on LogRocket Blog.

Top comments (0)