Kurs Vue.js · Moduł 1: Vue i Vite

Projekt: Panel Kontrolny NOVA LAB

4 min czytania
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ść computed ze średnim poziomem energii wszystkich modułów,
  • klasę zależną od statusu modułu, nadaną przez :class,
  • komunikat v-if i v-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 i reactive() 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?

Przydatne artykuły