Cours Vue.js · Module 13: Transitions et animations

Hooks d'animation JavaScript

3 min de lecture
Dans cette leçon7

Les classes CSS sont le « pilote automatique » des animations - elles fonctionnent très bien pour les transitions simples. Mais parfois tu as besoin d'un contrôle total sur les animations - par exemple des valeurs calculées dynamiquement, des animations pilotées par les données, ou une intégration avec des bibliothèques JS. Dans ces cas, Vue propose des hooks d'animation JavaScript - comme piloter une fusée à la main plutôt qu'en pilotage automatique.

Hooks disponibles

<Transition> émet des événements à chaque étape de l'animation. Tu peux les écouter :

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>

Hooks d'entrée - ordre d'exécution

  1. @before-enter(el) - appelé avant l'insertion de l'élément dans le DOM. Ici tu définis l'état initial de l'animation (par exemple opacity: 0, scale: 0.5).

  2. @enter(el, done) - appelé à la frame suivant l'insertion de l'élément. Ici tu lances l'animation réelle. Tu dois appeler done() quand l'animation se termine !

  3. @after-enter(el) - appelé après la fin de l'animation (après done()). Ici tu fais le ménage après l'animation (retirer les styles inline, etc.).

  4. @enter-cancelled(el) - appelé quand l'animation d'entrée est interrompue (par exemple quand l'utilisateur bascule rapidement l'élément).

Hooks de sortie - ordre analogue

  1. @before-leave(el) - état initial de la sortie, l'élément est encore visible
  2. @leave(el, done) - animation de sortie, tu dois appeler done() !
  3. @after-leave(el) - ménage après la sortie
  4. @leave-cancelled(el) - animation de sortie interrompue (seulement avec v-show)

L'attribut :css="false"

Quand tu utilises uniquement des hooks JS, ajoute :css="false" pour que Vue n'essaie pas d'appliquer des classes CSS ni d'écouter les événements transitionend/animationend :

1<Transition :css="false" @enter="onEnter" @leave="onLeave">
2  <div v-if="show">Panneau de contrôle</div>
3</Transition>

Sans cet attribut, Vue attendra à la fois le callback done() et l'événement de transition CSS - ce qui peut provoquer un comportement imprévisible.

Le callback done() - un élément clé

done() est obligatoire dans les hooks @enter et @leave. Il indique à Vue que l'animation est terminée et qu'il peut passer à l'étape suivante :

1function onBeforeEnter(el) {
2  // État initial - élément invisible
3  el.style.opacity = 0
4  el.style.transform = 'translateY(20px)'
5}
6
7function onEnter(el, done) {
8  // Force le reflow pour que le navigateur enregistre l'état initial
9  el.offsetHeight
10
11  // Lance l'animation
12  el.style.transition = 'all 0.5s ease'
13  el.style.opacity = 1
14  el.style.transform = 'translateY(0)'
15
16  // Prévient Vue quand l'animation se termine
17  el.addEventListener('transitionend', done, { once: true })
18}
19
20function onAfterEnter(el) {
21  // Ménage - retire la transition inline
22  el.style.transition = ''
23}

Sans appeler done(), Vue ne sait pas quand l'animation est terminée - dans le cas de @leave, l'élément ne sera jamais retiré du DOM.

Exemple pratique - animation pilotée par les données

Les hooks JS permettent des valeurs dynamiques, ce que les classes CSS ne peuvent pas offrir :

1function onEnter(el, done) {
2  // Direction d'animation dynamique basée sur les données
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}

Quand utiliser les hooks JS plutôt que le CSS ?

Utiliser les classes CSSUtiliser les hooks JS
Fade, slide simplesValeurs d'animation dynamiques
Durées fixesDurées dépendant des données
Transitions typiquesIntégration avec GSAP, Anime.js
La plupart des casSéquences d'animation complexes
Code de cette leçon : App.vue
1<script setup>
2import { ref } from 'vue'
3
4const showAlert = ref(false)
5
6function onBeforeEnter(el) {
7  el.style.opacity = 0
8  el.style.transform = 'scale(0.5)'
9}
10
11function onEnter(el, done) {
12  // Animation d'entrée sans CSS
13  el.offsetHeight // force le reflow
14  el.style.transition = 'all 0.6s ease'
15  el.style.opacity = 1
16  el.style.transform = 'scale(1)'
17  el.addEventListener('transitionend', done, { once: true })
18}
19
20function onLeave(el, done) {
21  el.style.transition = 'all 0.4s ease'
22  el.style.opacity = 0
23  el.style.transform = 'scale(0.5) rotate(10deg)'
24  el.addEventListener('transitionend', done, { once: true })
25}
26</script>
27
28<template>
29  <div class="nova-lab">
30    <h1>Hooks d'animation JavaScript</h1>
31
32    <button @click="showAlert = !showAlert" class="btn">
33      {{ showAlert ? "Fermer l'alerte" : "Afficher l'alerte" }}
34    </button>
35
36    <Transition
37      :css="false"
38      @before-enter="onBeforeEnter"
39      @enter="onEnter"
40      @leave="onLeave"
41    >
42      <div v-if="showAlert" class="alert">
43        ATTENTION : anomalie gravitationnelle détectée dans le secteur 7 !
44      </div>
45    </Transition>
46  </div>
47</template>
48
49<style scoped>
50.nova-lab {
51  background: #0a0e27;
52  color: #00ff88;
53  min-height: 100vh;
54  padding: 20px;
55  font-family: monospace;
56}
57h1 { color: #00ff88; }
58.btn {
59  background: #e74c3c;
60  color: white;
61  border: none;
62  padding: 10px 20px;
63  border-radius: 8px;
64  cursor: pointer;
65  margin: 15px 0;
66}
67.alert {
68  background: rgba(231, 76, 60, 0.2);
69  border: 2px solid #e74c3c;
70  color: #e74c3c;
71  padding: 20px;
72  border-radius: 12px;
73  font-size: 16px;
74}
75</style>

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quel hook JavaScript est appelé quand un élément entre dans le DOM ?

  2. 2. Que faut-il appeler à la fin du hook @enter pour informer Vue que l'animation est terminée ?

Tâches pratiques dans le jeu

  • Tri vertical

    Range les hooks JavaScript de Transition dans l'ordre où ils sont appelés (entrée) :

  • Éditeur de code

    Implémente @enter et @leave en utilisant el.style et le callback done().

  • Clique dans l'ordre

    Range le code du hook @enter dans le bon ordre :

  • Tri horizontal

    Range la syntaxe de Transition qui désactive les classes CSS :

  • Éditeur de code

    Utilise :css='false' et les hooks JS pour animer opacity et scale.

  • Tri horizontal

    Range la déclaration du hook @leave dans le template :