Vue 3 Tutorial: Übergänge mit Transition und TransitionGroup
geprüft am 2 September 2026 · 5 Min.
<Transition> animiert ein einzelnes Element beim Erscheinen und Verschwinden, <TransitionGroup> animiert eine Liste. Vue setzt CSS-Klassen, Ihr Stylesheet bestimmt den Effekt. Achtung: In Vue 3 heißen die Startklassen -enter-from und -leave-from, nicht -enter und -leave wie in Vue 2.
Ein Element, das schlagartig erscheint, wirkt wie ein Sprung. Vue liefert zwei eingebaute Komponenten, <Transition> und <TransitionGroup>, die im richtigen Moment CSS-Klassen setzen, um Ein- und Ausblendungen zu animieren. Keine Bibliothek zu installieren.
Das Prinzip
Umschließen Sie mit <Transition> ein Element, dessen Anzeige von einer Bedingung abhängt. Vue animiert es nicht selbst: Es fügt Klassen hinzu und entfernt sie wieder, und Ihr CSS entscheidet über den Effekt.
Sechs Klassen decken den gesamten Zyklus ab.
/* Eintritt */
.v-enter-from /* Ausgangszustand, unmittelbar vor dem Einfügen angewendet */
.v-enter-active /* während des gesamten Eintritts: hier gehört transition hin */
.v-enter-to /* Zielzustand */
/* Austritt */
.v-leave-from /* Ausgangszustand des Austritts */
.v-leave-active /* während des gesamten Austritts */
.v-leave-to /* Endzustand, unmittelbar vor dem Entfernen aus dem DOM */Das Präfix v- gehört zu einer Transition ohne Namen. Mit name="fade" heißen die Klassen fade-enter-from, fade-enter-active und so weiter.
In Vue 2 hießen die Startklassen .fade-enter und .fade-leave, ohne Suffix. Vue 3 hat sie in -enter-from und -leave-from umbenannt. Ein aus einem alten Artikel kopiertes Beispiel erzeugt daher beim Einblenden keinerlei Animation, ohne die geringste Fehlermeldung. Wenn Ihre Transition nichts tut, prüfen Sie zuerst diesen Punkt.
Die Verfügbarkeit animieren
In ProductDisplay.vue wechselt die Lagermeldung je nach überfahrener Variante zwischen zwei Absätzen. Umschließen Sie sie:
<Transition name="fade" mode="out-in">
<p v-if="inStock" key="in">En stock</p>
<p v-else key="out">En rupture</p>
</Transition>Beschreiben Sie dann den Effekt im Stylesheet, wie im Kapitel über Klassen und Styles:
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: translateY(-10px);
}
.fade-enter-active,
.fade-leave-active {
transition: opacity .3s ease, transform .3s ease;
}Fahren Sie über die Farbpunkte: Die Meldung blendet über, statt zu springen.
mode="out-in" wartet, bis das alte Element verschwunden ist, bevor das neue eingefügt wird. Ohne ihn existieren beide Absätze für einen Sekundenbruchteil gleichzeitig und überlappen sich.
Was Transition akzeptiert
Nur ein Element auf einmal. Das ist die wichtigste Einschränkung: <Transition> animiert ein einzelnes Kind, keine Liste.
Sie wird in drei Situationen ausgelöst: durch ein v-if, ein v-show oder einen Komponentenwechsel über <component :is>. Um eine Transition zwischen zwei Elementen desselben Typs zu erzwingen, geben Sie ihnen unterschiedliche keys, wie oben.
Eine Liste animieren
Für eine Liste braucht es <TransitionGroup>. Zwei Unterschiede: Sie akzeptiert mehrere Kinder und rendert selbst ein Containerelement, wenn Sie es mit tag verlangen.
Ersetzen Sie in ReviewList.vue das <ul>:
<template>
<div class="review-container">
<h3>Avis</h3>
<TransitionGroup name="liste" tag="ul">
<li v-for="review in reviews" :key="review.id">
{{ review.name }} a mis {{ review.rating }} étoiles
<br>
« {{ review.review }} »
</li>
</TransitionGroup>
</div>
</template>Jedes Kind braucht einen eindeutigen, stabilen key. Der Index taugt hier nicht: Er ändert sich bei jedem Einfügen, und Vue wüsste nicht mehr, welches Element neu ist. Geben wir jeder Bewertung beim Hinzufügen eine Kennung:
<script setup>
function addReview(review) {
reviews.value.push({ ...review, id: crypto.randomUUID() })
}
</script>crypto.randomUUID() ist in allen aktuellen Browsern verfügbar, auf Seiten, die über HTTPS oder von localhost ausgeliefert werden.
Das CSS bekommt eine weitere Klasse, -move, die die Bewegung der übrigen Elemente animiert, wenn ein Nachbar verschwindet:
.liste-enter-from,
.liste-leave-to {
opacity: 0;
transform: translateX(24px);
}
.liste-enter-active,
.liste-leave-active,
.liste-move {
transition: all .3s ease;
}Geben Sie mehrere Bewertungen ab: Jede gleitet herein, und die anderen ordnen sich sanft neu.
Damit -move beim Entfernen funktioniert, muss das ausscheidende Element aus dem Fluss genommen werden, sonst bewegen sich die anderen erst am Ende seiner Animation. Fügen Sie der Klasse -leave-active ein position: absolute hinzu, wenn Ihre Elemente gelöscht werden können.
Beim ersten Anzeigen animieren
Standardmäßig wird beim ersten Rendern nichts animiert. Das Attribut appear ändert das:
<Transition name="fade" appear>
<p>Visible dès le chargement, en fondu</p>
</Transition>CSS-Animationen und Hooks
transition ist nicht die einzige Option: Eine CSS-animation funktioniert ebenfalls, angewendet auf die Klasse -enter-active.
Um eine JavaScript-Animationsbibliothek zu steuern, löst <Transition> bei jedem Schritt Ereignisse aus:
<Transition
:css="false"
@before-enter="avantEntree"
@enter="entree"
@after-enter="apresEntree"
@leave="sortie"
>
<p v-if="visible">Contenu</p>
</Transition>Mit :css="false" verwaltet Vue die Klassen nicht mehr und überlässt Ihnen die Kontrolle. Die Funktionen enter und leave erhalten dann das Element und einen Callback done, der aufzurufen ist, wenn die Animation beendet ist:
function entree(el, done) {
// Animation mit der Bibliothek Ihrer Wahl
done()
}Bewegung ist nicht immer erwünscht
Manche Menschen deaktivieren Animationen auf Systemebene, vor allem um Übelkeit durch Bewegung zu vermeiden. Respektieren Sie diese Einstellung:
@media (prefers-reduced-motion: reduce) {
.fade-enter-active,
.fade-leave-active,
.liste-enter-active,
.liste-leave-active,
.liste-move {
transition: none;
}
}Die Oberfläche bleibt funktionsfähig, nur die Animation entfällt.
Das Ende des Tutorials
Ihre Anwendung zeigt ein Produkt und seine Varianten, verwaltet einen Warenkorb, validiert ein Formular und animiert ihre Zustandswechsel. Sie haben Reaktivität, Direktiven, Komponenten, Props, Ereignisse und Transitions behandelt: genug, um Vue im Alltag zu lesen und zu schreiben.
Für die Fortsetzung gibt es zwei Richtungen. Das Teilen von Zustand zwischen weit entfernten Komponenten mit Pinia, wenn das Hochreichen von Ereignissen mühsam wird. Und das Routing mit Vue Router, sobald die Anwendung mehrere Seiten hat.
<Transition> und <TransitionGroup> sind eingebaute Komponenten: Sie werden genau gleich geschrieben. Nur die Funktionen der JavaScript-Hooks wandern an eine andere Stelle, in die Option methods.
key.Häufige Fehler
.fade-enter und .fade-leave wurden in -enter-from und -leave-from umbenannt. Nichts wird animiert, und kein Fehler erscheint.global: { stubs: { 'transition-group': false } }, um das echte Rendering zu beobachten.