Cours Vue.js · Module 13: Transitions et animations
Hooks d'animation JavaScript
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
@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 exempleopacity: 0,scale: 0.5).@enter(el, done)- appelé à la frame suivant l'insertion de l'élément. Ici tu lances l'animation réelle. Tu dois appelerdone()quand l'animation se termine !@after-enter(el)- appelé après la fin de l'animation (aprèsdone()). Ici tu fais le ménage après l'animation (retirer les styles inline, etc.).@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
@before-leave(el)- état initial de la sortie, l'élément est encore visible@leave(el, done)- animation de sortie, tu dois appelerdone()!@after-leave(el)- ménage après la sortie@leave-cancelled(el)- animation de sortie interrompue (seulement avecv-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 CSS | Utiliser les hooks JS |
|---|---|
| Fade, slide simples | Valeurs d'animation dynamiques |
| Durées fixes | Durées dépendant des données |
| Transitions typiques | Intégration avec GSAP, Anime.js |
| La plupart des cas | Sé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. Quel hook JavaScript est appelé quand un élément entre dans le DOM ?
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 :