We use cookies to enhance your experience on the site
CodeWorlds

JavaScript Animation Hooks

CSS classes are the "autopilot" of animations — they work great for simple transitions. But sometimes you need full control over animations — e.g., dynamically computed values, data-driven animations, or integration with JS libraries. In such cases, Vue offers JavaScript animation hooks — like manual rocket steering instead of autopilot.

Available Hooks

<Transition>
emits events at each stage of the animation. You can listen to them:

1<Transition
2  :css="false"
3  @before-enter="onBeforeEnter"
4  @enter="onEnter"
5  @after-enter="onAfterEnter"
6  @enter-cancelled="onEnterCancelled"
7  @before-leave="onBeforeLeave"
8  @leave="onLeave"
9  @after-leave="onAfterLeave"
10  @leave-cancelled="onLeaveCancelled"
11>
12  <div v-if="show">...</div>
13</Transition>

Enter Hooks — Execution Order

  1. @before-enter(el)
    — called before the element is inserted into the DOM. Here you set the initial animation state (e.g.,
    opacity: 0
    ,
    scale: 0.5
    ).

  2. @enter(el, done)
    — called on the next frame after the element is inserted. Here you run the actual animation. You must call
    done()
    when the animation finishes!

  3. @after-enter(el)
    — called after the animation finishes (after
    done()
    ). Here you clean up after the animation (remove inline styles, etc.).

  4. @enter-cancelled(el)
    — called when the enter animation is interrupted (e.g., the user quickly toggles the element).

Leave Hooks — Analogous Order

  1. @before-leave(el)
    — initial state of leave, element is still visible
  2. @leave(el, done)
    — leave animation, you must call
    done()
    !
  3. @after-leave(el)
    — cleanup after leave
  4. @leave-cancelled(el)
    — leave animation interrupted (only with
    v-show
    )

The :css="false" Attribute

When using only JS hooks, add

:css="false"
so Vue doesn't try to apply CSS classes or listen for
transitionend
/
animationend
events:

1<Transition :css="false" @enter="onEnter" @leave="onLeave">
2  <div v-if="show">Control panel</div>
3</Transition>

Without this attribute, Vue will wait for both the

done()
callback and the CSS transition event — which can cause unpredictable behavior.

The done() Callback — A Key Element

done()
is mandatory in the
@enter
and
@leave
hooks. It tells Vue that the animation has finished and it can proceed to the next step:

1function onBeforeEnter(el) {
2  // Initial state — element invisible
3  el.style.opacity = 0
4  el.style.transform = 'translateY(20px)'
5}
6
7function onEnter(el, done) {
8  // Force reflow so the browser registers the initial state
9  el.offsetHeight
10
11  // Start the animation
12  el.style.transition = 'all 0.5s ease'
13  el.style.opacity = 1
14  el.style.transform = 'translateY(0)'
15
16  // Notify Vue when the animation finishes
17  el.addEventListener('transitionend', done, { once: true })
18}
19
20function onAfterEnter(el) {
21  // Cleanup — remove inline transition
22  el.style.transition = ''
23}

Without calling

done()
, Vue doesn't know when the animation has finished — in the case of
@leave
, the element will never be removed from the DOM.

Practical Example — Data-Driven Animation

JS hooks allow dynamic values, which CSS classes cannot provide:

1function onEnter(el, done) {
2  // Dynamic animation direction based on data
3  const direction = el.dataset.direction || 'left'
4  const offset = direction === 'left' ? '-100px' : '100px'
5
6  el.style.opacity = 0
7  el.style.transform = `translateX(${offset})`
8  el.offsetHeight // reflow
9
10  el.style.transition = 'all 0.4s ease-out'
11  el.style.opacity = 1
12  el.style.transform = 'translateX(0)'
13
14  el.addEventListener('transitionend', done, { once: true })
15}

When to Use JS Hooks Instead of CSS?

| Use CSS classes | Use JS hooks | |---|---| | Simple fade, slide | Dynamic animation values | | Fixed durations | Data-dependent durations | | Typical transitions | Integration with GSAP, Anime.js | | Most cases | Complex animation sequences |

Go to CodeWorlds