Usamos cookies para mejorar tu experiencia en el sitio
CodeWorlds

TransitionGroup - animacja list

Lista modułów stacji NOVA LAB ciągle się zmienia — dodajemy nowe systemy podtrzymywania życia, usuwamy uszkodzone sensory, sortujemy alerty po priorytecie. Za każdym razem chcemy, aby zmiany w liście były wizualnie płynne.

<TransitionGroup>
to komponent Vue zaprojektowany specjalnie do animowania elementów renderowanych przez
v-for
.

Podstawowe użycie

1<TransitionGroup name="list" tag="ul">
2  <li v-for="item in items" :key="item.id">
3    {{ item.name }}
4  </li>
5</TransitionGroup>

Każdy element dodawany do listy animuje się przy wejściu, a usuwany — przy wyjściu. To automatyczne zachowanie bazujące na tych samych klasach CSS co

<Transition>
.

Kluczowe różnice od
<Transition>

<TransitionGroup>
różni się od
<Transition>
w kilku istotnych punktach:

  1. Renderuje element DOM — w przeciwieństwie do

    <Transition>
    ,
    <TransitionGroup>
    domyślnie renderuje element HTML. Kontrolujesz go atrybutem
    tag
    :
    tag="ul"
    ,
    tag="div"
    ,
    tag="section"
    . Jeśli nie chcesz dodatkowego elementu, możesz ustawić
    tag="template"
    (Vue 3.5+).

  2. Każdy element musi mieć unikalne

    :key
    — Vue musi śledzić tożsamość poszczególnych elementów, aby wiedzieć które dodać, usunąć i przesunąć. Nigdy nie używaj indeksu tablicy jako key!

  3. Obsługuje wiele elementów jednocześnie — nie jest ograniczony do jednego elementu jak

    <Transition>
    . Wiele elementów może wchodzić i wychodzić w tym samym czasie.

  4. Dodatkowa klasa

    -move
    — animuje przesuwanie elementów, gdy lista się zmienia kolejnością. To unikalna funkcja
    <TransitionGroup>
    .

  5. Tryb

    mode
    nie jest obsługiwany — ponieważ nie przełączamy między jednym elementem a drugim.

Klasy CSS dla listy

TransitionGroup używa tych samych klas co Transition plus dodatkowa klasa

-move
:

1/* Wejście nowego elementu */
2.list-enter-active {
3  transition: all 0.5s ease;
4}
5.list-enter-from {
6  opacity: 0;
7  transform: translateX(30px);
8}
9
10/* Wyjście usuwanego elementu */
11.list-leave-active {
12  transition: all 0.5s ease;
13  position: absolute; /* WAŻNE! */
14}
15.list-leave-to {
16  opacity: 0;
17  transform: translateX(-30px);
18}
19
20/* Przesuwanie pozostałych elementów */
21.list-move {
22  transition: transform 0.5s ease;
23}

Move transitions — kluczowa mechanika

To najciekawsza funkcja

<TransitionGroup>
. Gdy dodajesz lub usuwasz element z listy, pozostałe elementy muszą się przesunąć na nowe pozycje. Vue automatycznie dodaje klasę
-move
do elementów, które zmieniają pozycję, i animuje ich ruch za pomocą transformacji CSS.

Aby move transitions działały poprawnie, elementy wychodzące muszą mieć

position: absolute
w klasie
-leave-active
. Dzięki temu wychodzący element "wychodzi z flow" i pozostałe mogą się płynnie przesunąć:

1.list-leave-active {
2  position: absolute;
3  /* Opcjonalnie: zachowaj szerokość */
4  width: 100%;
5}
6
7.list-move {
8  transition: transform 0.5s ease;
9}

Praktyczny przykład — lista alertów stacji

1<template>
2  <div class="alert-panel">
3    <button @click="addAlert">Dodaj alert</button>
4
5    <TransitionGroup name="alert" tag="div" class="alert-list">
6      <div
7        v-for="alert in alerts"
8        :key="alert.id"
9        class="alert-item"
10        :class="alert.level"
11      >
12        {{ alert.message }}
13        <button @click="removeAlert(alert.id)">x</button>
14      </div>
15    </TransitionGroup>
16  </div>
17</template>
18
19<script setup>
20import { ref } from 'vue'
21
22const alerts = ref([])
23let nextId = 1
24
25function addAlert() {
26  alerts.value.unshift({
27    id: nextId++,
28    message: `Alert #${nextId - 1}: Oxygen level check`,
29    level: Math.random() > 0.5 ? 'warning' : 'critical'
30  })
31}
32
33function removeAlert(id) {
34  alerts.value = alerts.value.filter(a => a.id !== id)
35}
36</script>
1.alert-enter-active, .alert-leave-active {
2  transition: all 0.4s ease;
3}
4.alert-enter-from {
5  opacity: 0;
6  transform: translateX(-30px);
7}
8.alert-leave-to {
9  opacity: 0;
10  transform: translateX(30px);
11}
12.alert-leave-active {
13  position: absolute;
14}
15.alert-move {
16  transition: transform 0.4s ease;
17}

Efekt: nowe alerty wchodzą z lewej, usuwane wychodzą w prawo, a pozostałe płynnie się przesuwają. Dokładnie jak na panelu alertów stacji kosmicznej!

Ir a CodeWorlds