Fonctionnement du composant Transition
Le composant <Transition> de Vue.js permet d'appliquer des effets d'animation lors de l'insertion, de la mise à jour ou de la suppression d'éléments dans le DOM. Pour qu'une transition soit correctement déclenchée, l'élément cible doit satisfaire l'une des conditions suivantes :
- Le rendu conditionnel via
v-if. - L'affichage conditionnel via
v-show. - L'utilisation de composants dynamiques.
L'attribut name permet de définir un préfixe personnalisé pour les classes CSS générées. Si aucun nom n'est spécifié, le préfixe par défaut est v-.
Cycle de vie des classes CSS
Le mécanisme de transition repose sur l'ajout et le retrait automatiques de classes CSS à des moments précis du cycle de vie de l'animation. Voici le déroulement pour une transition d'entrée (apparition) :
- Au début de l'insertion, les classes
*-enter-fromet*-enter-activesont appliquées. - À l'image suivante,
*-enter-fromest retirée et remplacée par*-enter-to. - Une fois l'animation terminée,
*-enter-activeet*-enter-tosont supprimées.
Pour une transition de sortie (disparition), le processus est similaire :
- Au déclenchmeent de la sortie, les classes
*-leave-fromet*-leave-activesont appliquées. - À l'image suivante,
*-leave-fromest retirée et remplacée par*-leave-to. - À la fin de l'anmiation,
*-leave-activeet*-leave-tosont supprimées.
Exemple de transition CSS native
<template>
<div class="layout-container">
<Transition name="opacity-shift">
<p v-if="isDisplayed">Texte avec effet de fondu</p>
</Transition>
<button @click="toggleDisplay">Basculer l'affichage</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const isDisplayed = ref(true);
const toggleDisplay = () => {
isDisplayed.value = !isDisplayed.value;
};
</script>
<style scoped>
.opacity-shift-enter-from,
.opacity-shift-leave-to {
opacity: 0;
}
.opacity-shift-enter-active,
.opacity-shift-leave-active {
transition: opacity 2.5s ease;
}
</style>
Utilisation des keyframes CSS dans Vue
Pour des animations plus complexes qu'une simple transition de propriétés, il est possible d'utiliser des @keyframes CSS. Les classes générées par Vue peuvent directement appeler ces animations via la propriété animation.
Application de classes personnalisées
Il est également possible de contourner le système de nommage par défaut de Vue en utilisant les attributs enter-active-class et leave-active-class directement sur le composant <Transition>.
<template>
<div class="layout-container">
<Transition
name="custom-zoom"
enter-active-class="zoom-in-effect"
leave-active-class="zoom-out-effect"
>
<p v-show="isDisplayed">Animation basée sur des keyframes</p>
</Transition>
<button @click="toggleDisplay">Basculer l'affichage</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const isDisplayed = ref(true);
const toggleDisplay = () => {
isDisplayed.value = !isDisplayed.value;
};
</script>
<style scoped>
@keyframes pulseScale {
0% { transform: scale(0.5); }
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
.zoom-in-effect {
transform-origin: center;
animation: pulseScale 0.8s ease-out;
}
.zoom-out-effect {
transform-origin: center;
animation: pulseScale 0.8s ease-in reverse;
}
</style>
Intégration de la bibliothèque Animate.css
Pour enrichir les interfaces sans écrire de CSS complexe, la bibliothèque Animate.css peut être intégrée. Elle s'utilise en appliquant ses classes utilitaires directement dans les attributs de transition de Vue.
Gestion du rendu initial et des durées
- Animation au chargement : Par défaut, la transition ne s'applique pas au premier rendu. L'ajout de l'attribut
appearforce l'exécution de l'animation lors du montage initial du composant. - Conflit de durées : Si vous combinez une transition CSS native avec une animation Animate.css, Vue peut avoir du mal à déterminer la fin de l'animation. Vous pouvez forcer le type d'animation à écouter avec l'attribut
type="animation"outype="transition". - Durées personnalisées : L'attribut
:durationpermet de spécifier une durée exacte en millisecondes. Il accepte soit un nombre unique, soit un objet pour dissocier les durées d'entrée et de sortie (ex::duration="{ enter: 3000, leave: 6000 }").
Exemple combiné avec Animate.css
<template>
<div class="layout-container">
<Transition
appear
:duration="{ enter: 3000, leave: 4000 }"
name="fade-combo"
enter-active-class="animate__animated animate__fadeInLeft fade-enter-active"
leave-active-class="animate__animated animate__fadeOutRight fade-leave-active"
appear-active-class="animate__animated animate__zoomIn"
>
<p v-show="isDisplayed">Élément avec Animate.css et transition CSS</p>
</Transition>
<button @click="toggleDisplay">Basculer l'affichage</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const isDisplayed = ref(true);
const toggleDisplay = () => {
isDisplayed.value = !isDisplayed.value;
};
</script>
<style scoped>
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 3s linear;
}
</style>