Kurs Vue.js · Moduł 1: Vue i Vite
Projekt: Panel Kontrolny NOVA LAB
W tej lekcji5
Gratulacje, kadetcie! Dotarliśmy do finalnego projektu pierwszego modułu na stacji NOVA LAB. Czas połączyć wszystkie poznane umiejętności w jeden funkcjonalny system.
Każdy moduł stacji ma dziś własny ekran, a dyżurny inżynier biega między nimi, żeby sprawdzić, czy wszystko działa. Potrzebny jest jeden panel, który zbierze stan całej stacji w jednym miejscu - i właśnie taki panel zbudujesz.
Cel projektu
Zbuduj kompletny Panel Kontrolny NOVA LAB - aplikację Vue.js, która łączy wszystkie koncepty z tego modułu:
- Vue.js i Vite - nowoczesny framework reaktywny
- Single File Components - organizacja kodu w plikach .vue
- Struktura aplikacji - poprawna hierarchia komponentów
- Vue DevTools - narzędzia diagnostyczne do debugowania
Wymagania projektu
Twój Panel Kontrolny powinien zawierać:
1. Sekcja statusu stacji
Wyświetl nazwę stacji, aktualny status (ONLINE/OFFLINE) oraz datę ostatniej aktualizacji. Użyj interpolacji Vue do wyświetlania danych.
2. Lista modułów stacji
Stwórz tablicę z minimum 4 modułami stacji (np. Laboratorium, Reaktor, Komunikacja, Nawigacja). Każdy moduł powinien mieć nazwę, status i poziom energii.
3. Stylowanie komponentu
Użyj sekcji <style scoped> aby nadać aplikacji wygląd panelu kosmicznego - ciemne tło, neonowe kolory, futurystyczny design.
Co Czeka w Starterze
Starter w edytorze ma już dane i szkielet szablonu. Proste wartości, takie jak nazwa stacji, trzymają kontenery ref(), a tablicę modułów obejmuje nowa funkcja reactive(). Działa podobnie, ale przyjmuje obiekt lub tablicę i sprawia, że reaktywne są wszystkie ich pola, a do elementów sięgasz bez .value:
1import { ref, reactive } from 'vue'
2
3const stationName = ref('NOVA LAB')
4
5const modules = reactive([
6 { id: 1, name: 'Laboratorium', status: 'active', energy: 85 },
7 { id: 2, name: 'Reaktor', status: 'active', energy: 92 }
8 // ...i kolejne moduły ze startera
9])Gdy zmienisz modules[0].energy, pasek na ekranie przesunie się sam, a tablica pozostaje zwykłą tablicą z tymi samymi metodami. Szczegóły reactive() poznasz w Reaktorze Energetycznym.
Karty modułów powstają dzięki dyrektywie v-for, która powtarza element dla każdego elementu tablicy. Atrybut :key nadaje każdej kopii unikalny identyfikator, a :style ustawia szerokość paska energii, tak jak :class ustawia klasę:
1<div v-for="mod in modules" :key="mod.id" class="module-card">
2 <h3>{{ mod.name }}</h3>
3 <div class="energy-bar">
4 <div class="energy-fill" :style="{ width: mod.energy + '%' }"></div>
5 </div>
6</div>Vue wstawi tyle kart, ile elementów ma tablica, więc piąty moduł dopisany do danych od razu doda piątą kartę, bez zmian w szablonie. Renderowanie list omówimy dokładnie w Pracowni Hologramów.
Rozbudowa Panelu
Na tym starter się kończy. Rozbuduj go o narzędzia, które poznałeś w Strefie Startowej:
- przycisk z
@click, który przełącza status stacji między ONLINE i OFFLINE, - wartość
computedze średnim poziomem energii wszystkich modułów, - klasę zależną od statusu modułu, nadaną przez
:class, - komunikat
v-ifiv-else, gdy energia któregoś modułu spadnie poniżej 50%, watch, który zapisze w konsoli każdą zmianę statusu stacji.
Pierwszy punkt możesz zacząć od takiej funkcji. Korzysta ona z operatora warunkowego: gdy stacja jest ONLINE, przełącza ją na OFFLINE, i odwrotnie:
1function toggleStation() {
2 stationStatus.value = stationStatus.value === 'ONLINE' ? 'OFFLINE' : 'ONLINE'
3}Podepnij ją pod przycisk zapisem @click="toggleStation", a napis w nagłówku zmieni się przy każdym kliknięciu. Polecam budować panel krok po kroku: po każdej zmianie zerknij na podgląd i na zakładkę Components w DevTools, zamiast pisać wszystko naraz.
Wskazówki
- Zacznij od sekcji
<script setup>z danymi reaktywnymi - Użyj
ref()dla prostych wartości ireactive()dla obiektów - Pamiętaj o sekcji
<template>z poprawną składnią Vue - Dodaj
<style scoped>na końcu komponentu
Starter stawia <script setup> na samej górze pliku. To również poprawna kolejność: Vue jej nie narzuca, a przewodnik stylu zaleca tylko, żeby w całym projekcie była spójna, a styl stał na końcu. Gotowy panel wyślesz mentorowi w kolejnym zadaniu, więc opisz w nim, gdzie użyłeś ref(), dyrektyw, computed i watch.
Eksperymentuj z kodem poniżej i rozbuduj go o własne pomysły!
Zapamiętaj: panel kontrolny to wszystkie narzędzia Strefy Startowej w jednym module - dane w kontenerach, szablon, który je pokazuje, i style zamykające całość w obudowie.
Kod do tej lekcji: App.vue
1<script setup>
2import { ref, reactive } from 'vue'
3
4// Panel Kontrolny NOVA LAB - projekt końcowy modułu 1
5const stationName = ref('NOVA LAB')
6const stationStatus = ref('ONLINE')
7const lastUpdate = ref(new Date().toLocaleString())
8
9const modules = reactive([
10 { id: 1, name: 'Laboratorium', status: 'active', energy: 85 },
11 { id: 2, name: 'Reaktor', status: 'active', energy: 92 },
12 { id: 3, name: 'Komunikacja', status: 'warning', energy: 45 },
13 { id: 4, name: 'Nawigacja', status: 'active', energy: 78 }
14])
15
16// TODO: Dodaj więcej modułów stacji
17// TODO: Dodaj funkcje przełączania statusu
18// TODO: Dodaj obliczanie średniej energii
19</script>
20
21<template>
22 <div class="control-panel">
23 <header>
24 <h1>{{ stationName }} - Panel Kontrolny</h1>
25 <p>Status: {{ stationStatus }} | Ostatnia aktualizacja: {{ lastUpdate }}</p>
26 </header>
27
28 <section class="modules">
29 <h2>Moduły stacji</h2>
30 <!-- TODO: Wyświetl listę modułów z v-for -->
31 <!-- TODO: Dodaj dynamiczne klasy na podstawie statusu -->
32 <div v-for="mod in modules" :key="mod.id" class="module-card">
33 <h3>{{ mod.name }}</h3>
34 <p>Status: {{ mod.status }}</p>
35 <div class="energy-bar">
36 <div class="energy-fill" :style="{ width: mod.energy + '%' }"></div>
37 </div>
38 <span>{{ mod.energy }}%</span>
39 </div>
40 </section>
41 </div>
42</template>
43
44<style scoped>
45.control-panel {
46 background: #0a0a2e;
47 color: #e0e0ff;
48 min-height: 100vh;
49 padding: 2rem;
50 font-family: 'Courier New', monospace;
51}
52header { text-align: center; border-bottom: 1px solid #333; padding-bottom: 1rem; }
53h1 { color: #00d4ff; }
54.modules { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1rem; }
55.module-card { background: #1a1a4e; padding: 1rem; border-radius: 8px; flex: 1; min-width: 200px; border: 1px solid #333; }
56.energy-bar { background: #222; border-radius: 4px; height: 8px; margin: 0.5rem 0; }
57.energy-fill { background: #00d4ff; height: 100%; border-radius: 4px; transition: width 0.3s; }
58</style>Widzisz błąd w tej lekcji?