Kurs Vue.js · Moduł 1: Vue i Vite
Czym jest Vue.js?
W tej lekcji5
Witaj w Strefie Startowej NOVA LAB! Jestem Dr. Nova i będę Twoim mentorem. To tutaj inicjalizujemy wszystkie systemy, które polecą na Marsa. Vue.js to framework, który napędza nasze interfejsy misji - od paneli sterowania po systemy podtrzymywania życia.
Wyobraź sobie panel podtrzymywania życia zbudowany bez żadnego frameworka. Poziom tlenu zmienia się co kilka sekund, a każdy nowy odczyt trzeba ręcznie wpisać w odpowiednie miejsce strony:
1// Bez frameworka: każdy odczyt to ręczna aktualizacja ekranu
2const oxygenDisplay = document.querySelector('#oxygen')
3oxygenDisplay.textContent = '98.5%'Ten kod działa, ale tylko raz. Przy kolejnym odczycie musisz znowu odszukać element i podmienić tekst - i tak dla każdego wskaźnika, bo liczba w kodzie i napis na ekranie nie są ze sobą połączone. Vue odwraca ten układ: opisujesz, co ekran ma pokazywać dla danych misji, a framework sam pilnuje, żeby obraz się z nimi zgadzał.
Czego się nauczysz
- czym jest Vue.js i dlaczego nazywamy go frameworkiem progresywnym,
- jak wygląda najprostszy komponent z
ref()i wąsami{{ }}, - na czym opierają się trzy protokoły NOVA LAB,
- co wniosło Vue 3 i z jakich narzędzi składa się ekosystem misji.
Vue.js - Framework Misji Kosmicznych
Vue.js (wymawiane /vjuː/, jak angielskie "view") to progresywny framework JavaScript do budowania interfejsów. Stworzył go Evan You, a pierwsza wersja ukazała się w 2014 roku. W 2087 roku nadal jest używany, bo sprawdził się w najbardziej ekstremalnych warunkach - w kosmosie.
Dlaczego "progresywny"?
Vue można wprowadzać stopniowo - od prostego interfejsu, po zaawansowany system sterowania statkiem. To jak budowanie rakiety:
- Najpierw prototyp (podstawowy Vue)
- Potem pełna rakieta (komponenty, routing)
- Na końcu statek międzyplanetarny (pełna aplikacja)
Vue możesz dołączyć jednym skryptem do istniejącej strony albo zbudować z nim całą aplikację z narzędziem Vite. W NOVA LAB od pierwszego dnia pracujemy na pełnym zestawie z Vite i plikami .vue - tak powstają prawdziwe projekty i taki start polecam.
Protokoły NOVA LAB
Nasze zasady kodowania opierają się na trzech filarach:
1. Prostota (Protokół KISS)
Najprostszy komponent ma dwie części. Szablon w znaczniku <template> opisuje, co widać na ekranie, a sekcja <script setup> przechowuje dane. Funkcję ref sprowadzamy instrukcją import z pakietu vue i przekazujemy jej wartość początkową:
1<template>
2 <h1>{{ missionName }}</h1>
3</template>
4
5<script setup>
6import { ref } from 'vue'
7const missionName = ref('MARS ONE')
8</script>Funkcja ref() tworzy reaktywny kontener: Vue obserwuje jego zawartość i wie, kiedy się zmieniła. Podwójne nawiasy klamrowe, czyli wąsy, wstawiają do szablonu aktualną wartość kontenera. Znacznik <h1> pozostał zwykłym HTML-em - Vue dołożyło tylko miejsce na dane. Gdy nazwa misji się zmieni, napis odświeży się sam, bez szukania elementu na stronie.
Kontenerów może być dowolnie wiele, a wąsy da się wplatać w zwykły tekst, więc przed nimi i za nimi może stać dowolny napis:
1<template>
2 <h2>{{ stationName }}</h2>
3 <p>Załoga: {{ crewCount }} osób</p>
4 <p>Rezerwa tlenu: {{ oxygenReserve }}%</p>
5</template>
6
7<script setup>
8import { ref } from 'vue'
9
10const stationName = ref('Baza Nova')
11const crewCount = ref(4)
12const oxygenReserve = ref(92)
13</script>Każda wartość dostała własny ref(), a jeden import obsłużył wszystkie trzy. Napisy "Załoga:" i "%" pozostały zwykłym tekstem - Vue podmienia wyłącznie to, co stoi w wąsach. Oba narzędzia rozbierzemy na części w lekcji o pierwszym systemie Vue.
2. Niezawodność (Protokół ZERO-FAULT)
Kod Vue jest przewidywalny - krytyczne dla systemów podtrzymywania życia. Szablon deklaruje, jak ekran ma wyglądać dla danego stanu, a Ty zmieniasz wyłącznie dane, nigdy bezpośrednio stronę.
3. Wydajność (Protokół LIGHT)
Vue używa Virtual DOM - każdy kilobajt mniej to więcej paliwa na pokładzie. Po zmianie danych Vue buduje w pamięci lekki opis ekranu, porównuje go z poprzednim i nanosi na stronę tylko różnice, a fragmenty, które nigdy się nie zmieniają, kompilator oznacza tak, żeby je pomijać.
Vue 3 - Generacja Kosmiczna
Vue 3 ukazał się w 2020 roku i to jego używamy w NOVA LAB - Vue 2 przestał być wspierany z końcem 2023 roku. Vue 3 wprowadził zmiany kluczowe dla misji kosmicznych:
- Composition API - modułowa organizacja systemów
- Lepsza wydajność - mniejszy bundle, szybsze reakcje
- TypeScript - typowanie eliminuje błędy przed startem
- Teleport, Suspense - zaawansowane techniki UI
Composition API to styl, który widziałeś przed chwilą: dane i funkcje piszesz w <script setup>. Starsze Options API nadal działa, ale go nie używamy. Teleport przenosi fragment szablonu w inne miejsce strony, a Suspense pokazuje ekran oczekiwania na dane - dokumentacja Vue wciąż oznacza go jako eksperymentalny.
Ekosystem NOVA LAB
| Narzędzie | Zastosowanie w misji |
|---|---|
| Vite | Silnik kompilacji - błyskawiczny |
| Vue Router | Nawigacja między sekcjami bazy |
| Pinia | Centralny komputer misji |
| Vitest | Testy przed startem |
| VueUse | Protokoły wielokrotnego użytku |
| Nuxt | Serwer bazy marsjańskiej |
Vue Router i Pinia to oficjalne biblioteki zespołu Vue. Pinia zarządza stanem wspólnym dla całej aplikacji - w świecie Vue nie sięgasz po Redux ani Context API znane z Reacta. Vite napisał ten sam autor co Vue, a w następnej lekcji uruchomisz ten silnik.
W edytorze poniżej czeka panel z licznikiem energii. Klikaj plus i minus, obserwuj zmieniający się status i odszukaj w kodzie wąsy oraz ref().
Zapamiętaj: Vue to progresywny framework, w którym opisujesz, co ma pokazać ekran, a system sam pilnuje, żeby obraz zawsze zgadzał się z danymi misji.
Kod do tej lekcji: src/App.vue
1<template>
2 <div class="nova-lab">
3 <header class="lab-header">
4 <h1>NOVA LAB - Strefa Startowa</h1>
5 <p class="subtitle">Rok 2087 - Centrum Badawcze Misji Mars</p>
6 </header>
7
8 <main class="lab-content">
9 <section class="welcome-panel">
10 <h2>Witaj, Inżynierze!</h2>
11 <p>
12 To jest Twój pierwszy komponent Vue.js w NOVA LAB.
13 Stworzyliśmy go przy użyciu Vite - błyskawicznie szybkiego narzędzia budującego.
14 </p>
15 <p>
16 <strong>Dr. Nova:</strong> "Każdy wielki system zaczyna się od małego komponentu.
17 Twoja podróż do Marsa właśnie się rozpoczęła!"
18 </p>
19 </section>
20
21 <section class="info-panel">
22 <h3>Czym jest Vue.js?</h3>
23 <ul>
24 <li>Progresywny framework JavaScript</li>
25 <li>Reaktywny system danych</li>
26 <li>Komponenty wielokrotnego użytku</li>
27 <li>Świetne narzędzia deweloperskie</li>
28 </ul>
29 </section>
30
31 <section class="counter-demo">
32 <h3>Interaktywny Licznik Energii</h3>
33 <div class="counter">
34 <button @click="powerLevel--" class="btn">-</button>
35 <span class="power-display">{{ powerLevel }}%</span>
36 <button @click="powerLevel++" class="btn">+</button>
37 </div>
38 <p class="status" :class="powerStatus">
39 Status: {{ powerStatusText }}
40 </p>
41 </section>
42 </main>
43
44 <footer class="lab-footer">
45 <p>NOVA LAB © 2087 - Przygotowanie do kolonizacji Marsa</p>
46 </footer>
47 </div>
48</template>
49
50<script setup>
51import { ref, computed } from 'vue'
52
53const powerLevel = ref(50)
54
55const powerStatus = computed(() => {
56 if (powerLevel.value < 20) return 'critical'
57 if (powerLevel.value < 50) return 'warning'
58 return 'nominal'
59})
60
61const powerStatusText = computed(() => {
62 if (powerLevel.value < 20) return 'KRYTYCZNY'
63 if (powerLevel.value < 50) return 'OSTRZEŻENIE'
64 return 'NOMINALNY'
65})
66</script>
67
68<style>
69.nova-lab {
70 min-height: 100vh;
71 background: linear-gradient(135deg, #0a0e27 0%, #1a1e37 100%);
72 color: #e0e0e0;
73 font-family: 'Segoe UI', system-ui, sans-serif;
74 padding: 2rem;
75}
76
77.lab-header {
78 text-align: center;
79 margin-bottom: 2rem;
80 padding-bottom: 1rem;
81 border-bottom: 2px solid #00ff88;
82}
83
84.lab-header h1 {
85 color: #00ff88;
86 font-size: 2.5rem;
87 margin: 0;
88 text-shadow: 0 0 20px rgba(0, 255, 136, 0.5);
89}
90
91.subtitle {
92 color: #00b4d8;
93 margin-top: 0.5rem;
94}
95
96.lab-content {
97 max-width: 800px;
98 margin: 0 auto;
99}
100
101section {
102 background: rgba(26, 30, 55, 0.8);
103 border: 1px solid #00b4d8;
104 border-radius: 12px;
105 padding: 1.5rem;
106 margin-bottom: 1.5rem;
107}
108
109h2, h3 {
110 color: #00ff88;
111 margin-top: 0;
112}
113
114ul {
115 list-style: none;
116 padding: 0;
117}
118
119ul li {
120 padding: 0.5rem 0;
121 border-bottom: 1px solid rgba(0, 180, 216, 0.3);
122}
123
124ul li::before {
125 content: "→ ";
126 color: #00ff88;
127}
128
129.counter {
130 display: flex;
131 align-items: center;
132 justify-content: center;
133 gap: 1rem;
134 margin: 1rem 0;
135}
136
137.btn {
138 background: #00b4d8;
139 color: #0a0e27;
140 border: none;
141 width: 50px;
142 height: 50px;
143 border-radius: 50%;
144 font-size: 1.5rem;
145 cursor: pointer;
146 transition: all 0.3s;
147}
148
149.btn:hover {
150 background: #00ff88;
151 transform: scale(1.1);
152}
153
154.power-display {
155 font-size: 2rem;
156 font-weight: bold;
157 color: #00ff88;
158 min-width: 100px;
159 text-align: center;
160}
161
162.status {
163 text-align: center;
164 padding: 0.5rem;
165 border-radius: 8px;
166 font-weight: bold;
167}
168
169.status.nominal { background: rgba(0, 255, 136, 0.2); color: #00ff88; }
170.status.warning { background: rgba(255, 170, 0, 0.2); color: #ffaa00; }
171.status.critical { background: rgba(255, 68, 68, 0.2); color: #ff4444; }
172
173.lab-footer {
174 text-align: center;
175 margin-top: 2rem;
176 color: #666;
177 font-size: 0.9rem;
178}
179</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. Co oznacza, że Vue.js jest progresywnym frameworkiem?
2. Która z poniższych jest nową cechą Vue 3?
3. Która biblioteka jest oficjalnym narzędziem zespołu Vue do zarządzania stanem aplikacji?
Zadania praktyczne w grze
- Edytor kodu
Uzupełnij komponent Vue tak, aby wyświetlał powitanie z NOVA LAB. Użyj ref() i interpolacji {{ }}.
- Klikanie w kolejności
Ułóż składnię interpolacji danych w Vue template:
- Edytor kodu
Stwórz komponent z kilkoma zmiennymi ref() i wyświetl je w template za pomocą {{ }}.