Kurs Vue.js · Moduł 13: Przejścia i animacje
Transition między routami
W tej lekcji5
W NOVA LAB przechodzenie między sekcjami stacji - z centrum dowodzenia do laboratorium, z reaktora do hangaru - powinno być płynne i naturalne. Vue Router wspiera animacje przejść między stronami dzięki integracji z komponentem <Transition>.
RouterView + Transition
Aby animować zmianę widoku routera, używasz slot API na <RouterView>. Vue Router udostępnia aktualny komponent jako zmienną slotową:
1<RouterView v-slot="{ Component }">
2 <Transition name="page" mode="out-in">
3 <component :is="Component" />
4 </Transition>
5</RouterView>Jak to działa krok po kroku:
<RouterView v-slot="{ Component }">- router dostarcza aktualny komponent strony jakoComponent<Transition name="page" mode="out-in">- opakowujesz dynamiczny komponent w Transition<component :is="Component" />- renderujesz dynamiczny komponent strony
Trzy kluczowe zasady:
- Użyj
v-slot="{ Component }"- nie możesz bezpośrednio owinąć<RouterView>w<Transition>(to nie zadziała w Vue 3) - Zawsze dodaj
mode="out-in"- bez tego stara i nowa strona będą animowane jednocześnie, co wygląda chaotycznie - Nie dodawaj
:keyna<component>- Vue Router automatycznie reaguje na zmianę routy
Odpowiednie klasy CSS:
1.page-enter-active,
2.page-leave-active {
3 transition: all 0.3s ease;
4}
5
6.page-enter-from {
7 opacity: 0;
8 transform: translateX(20px);
9}
10
11.page-leave-to {
12 opacity: 0;
13 transform: translateX(-20px);
14}Per-route transitions
Każda sekcja stacji NOVA LAB może mieć inny typ animacji - centrum dowodzenia wsuwa się z lewej, panel alertów wyskakuje z dołu. Użyj pola meta w definicji routy, aby przypisać nazwę animacji:
1const routes = [
2 {
3 path: '/dashboard',
4 component: Dashboard,
5 meta: { transition: 'slide-left' }
6 },
7 {
8 path: '/settings',
9 component: Settings,
10 meta: { transition: 'slide-right' }
11 },
12 {
13 path: '/alerts',
14 component: Alerts,
15 meta: { transition: 'slide-up' }
16 }
17]W template odczytaj nazwę animacji z obiektu route:
1<RouterView v-slot="{ Component, route }">
2 <Transition :name="route.meta.transition || 'fade'" mode="out-in">
3 <component :is="Component" />
4 </Transition>
5</RouterView>Zwróć uwagę na || 'fade' - to fallback dla routów bez zdefiniowanej animacji. Slot v-slot daje dostęp zarówno do Component (aktualny komponent strony) jak i route (obiekt routy z meta danymi).
Dynamiczne animacje na podstawie kierunku nawigacji
Możesz zmieniać animację w zależności od tego, czy użytkownik nawiguje "w przód" czy "w tył":
1<script setup>
2import { ref } from 'vue'
3import { useRouter } from 'vue-router'
4
5const transitionName = ref('slide-left')
6const router = useRouter()
7
8router.beforeEach((to, from) => {
9 // Porównaj indeksy stron aby określić kierunek
10 const toDepth = to.path.split('/').length
11 const fromDepth = from.path.split('/').length
12
13 transitionName.value = toDepth < fromDepth ? 'slide-right' : 'slide-left'
14})
15</script>
16
17<template>
18 <RouterView v-slot="{ Component }">
19 <Transition :name="transitionName" mode="out-in">
20 <component :is="Component" />
21 </Transition>
22 </RouterView>
23</template>Z KeepAlive
Możesz łączyć Transition z KeepAlive, aby cache'ować widoki stron. To przydatne gdy użytkownik często przechodzi między tymi samymi sekcjami stacji i nie chcesz tracić stanu (np. pozycji scrolla, wprowadzonych danych):
1<RouterView v-slot="{ Component }">
2 <Transition name="fade" mode="out-in">
3 <KeepAlive :max="5">
4 <component :is="Component" />
5 </KeepAlive>
6 </Transition>
7</RouterView>Kolejność jest istotna - <Transition> na zewnątrz, <KeepAlive> wewnątrz. Atrybut :max="5" ogranicza liczbę cache'owanych komponentów, aby nie zużywać nadmiernej ilości pamięci.
Uwagi praktyczne
- Animacje przejść między stronami powinny być krótkie (200-400ms) - użytkownik chce szybko zobaczyć treść
- Unikaj ciężkich animacji (np. 3D transforms) na urządzeniach mobilnych
- Testuj animacje na wolniejszych urządzeniach - efekt, który wygląda świetnie na szybkim komputerze, może lagować na tablecie
- Preferuj
opacityitransform- te właściwości są akcelerowane przez GPU
Kod do tej lekcji: App.vue
1<script setup>
2import { ref } from 'vue'
3
4// Symulacja routera z komponentami
5const currentRoute = ref('home')
6const routes = {
7 home: { name: 'Panel główny', icon: '' },
8 sensors: { name: 'Czujniki', icon: '' },
9 crew: { name: 'Załoga', icon: '' }
10}
11</script>
12
13<template>
14 <div class="nova-lab">
15 <h1>Transition między routami</h1>
16 <p style="color: #888;">Symulacja Transition z RouterView</p>
17
18 <nav class="nav">
19 <button
20 v-for="(route, key) in routes"
21 :key="key"
22 @click="currentRoute = key"
23 :class="{ active: currentRoute === key }"
24 class="nav-link"
25 >
26 {{ route.icon }} {{ route.name }}
27 </button>
28 </nav>
29
30 <!-- Symulacja: RouterView v-slot + Transition -->
31 <Transition name="page" mode="out-in">
32 <div :key="currentRoute" class="page">
33 <h2>{{ routes[currentRoute].icon }} {{ routes[currentRoute].name }}</h2>
34 <p>Zawartość strony: {{ currentRoute }}</p>
35 </div>
36 </Transition>
37 </div>
38</template>
39
40<style scoped>
41.nova-lab {
42 background: #0a0e27;
43 color: #00ff88;
44 min-height: 100vh;
45 padding: 20px;
46 font-family: monospace;
47}
48h1 { color: #00ff88; }
49.nav {
50 display: flex;
51 gap: 8px;
52 margin: 15px 0;
53 border-bottom: 2px solid #1a1e3a;
54 padding-bottom: 10px;
55}
56.nav-link {
57 background: transparent;
58 color: #00b4d8;
59 border: 1px solid transparent;
60 padding: 8px 16px;
61 border-radius: 6px 6px 0 0;
62 cursor: pointer;
63}
64.nav-link.active {
65 background: rgba(0, 180, 216, 0.15);
66 border-color: #00b4d8;
67 border-bottom-color: transparent;
68}
69.page {
70 background: rgba(0, 255, 136, 0.05);
71 border: 2px solid #00ff88;
72 padding: 30px;
73 border-radius: 0 12px 12px 12px;
74 min-height: 150px;
75}
76
77/* Przejście strony */
78.page-enter-active,
79.page-leave-active {
80 transition: all 0.3s ease;
81}
82.page-enter-from {
83 opacity: 0;
84 transform: translateY(20px);
85}
86.page-leave-to {
87 opacity: 0;
88 transform: translateY(-20px);
89}
90</style>Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jak dodać animację przejścia między stronami w Vue Router?
2. Jak zdefiniować nazwę animacji per-route w Vue Router?
Zadania praktyczne w grze
- Układanie w pionie
Ułóż zagnieżdżenie komponentów dla animacji routingu:
- Edytor kodu
Owiń RouterView v-slot w <Transition> z mode='out-in'.
- Układanie w poziomie
Ułóż składnię RouterView z v-slot:
- Klikanie w kolejności
Ułóż kod dynamicznej nazwy transition per-route: