Kurs Vue.js · Moduł 6: Komponenty
Rejestracja i Import Komponentów
W tej lekcji4
Dr. Nova wyjaśnia: "W NOVA LAB każdy moduł habitatu musi być oficjalnie zarejestrowany w systemie stacji, zanim będzie mógł funkcjonować. Podobnie komponenty Vue muszą być zaimportowane lub zarejestrowane, aby można ich było użyć w szablonie."
Co się stanie, gdy wpiszesz w szablonie <StatusBar />, ale nie powiesz Vue, skąd wziąć ten komponent? Vue nie odgadnie ścieżki do pliku. W konsoli pojawi się ostrzeżenie "Failed to resolve component: StatusBar", a na stronie zostanie pusty, nieznany przeglądarce element. Rejestracja to właśnie ta informacja: jaki komponent kryje się pod daną nazwą.
Import w <script setup>
Najczęstszy i zalecany sposób to import lokalny w bloku <script setup>. Zaimportowany komponent jest automatycznie dostępny w szablonie - nie trzeba go nigdzie rejestrować! Zobacz panel dowodzenia, który składa się z trzech modułów:
1<!-- MissionControl.vue -->
2<template>
3 <div class="control-panel">
4 <ModuleCard />
5 <StatusBar />
6 <AlertPanel />
7 </div>
8</template>
9
10<script setup>
11// Wystarczy zaimportować - komponent jest od razu dostępny w template!
12import ModuleCard from './components/ModuleCard.vue'
13import StatusBar from './components/StatusBar.vue'
14import AlertPanel from './components/AlertPanel.vue'
15</script>Plik .vue udostępnia swój komponent jako eksport domyślny, dlatego importujemy go bez klamer, a nazwa nadana w imporcie staje się nazwą znacznika w szablonie. Ścieżka zaczyna się od ./, więc jest względna. Równie dobrze możesz użyć aliasu z konfiguracji Vite: @/components/StatusBar.vue.
Zwróć uwagę: w Options API (bez <script setup>) musielibyśmy dodatkowo rejestrować komponenty w opcji components: {}. W Composition API z <script setup> ten krok jest zbędny - Vue automatycznie rozpoznaje zaimportowane komponenty. Porównaj oba zapisy:
1<!-- Options API - wymaga ręcznej rejestracji -->
2<script>
3import ModuleCard from './components/ModuleCard.vue'
4
5export default {
6 components: {
7 ModuleCard // Konieczna rejestracja!
8 }
9}
10</script>
11
12<!-- Composition API <script setup> - auto-rejestracja -->
13<script setup>
14import ModuleCard from './components/ModuleCard.vue'
15// Gotowe! Nie trzeba nic więcej.
16</script>Import wygląda identycznie w obu wersjach - różnica tkwi w tym, co dzieje się po nim. Kompilator <script setup> sam zauważa, że ModuleCard jest używany w szablonie, i podpina go za Ciebie. Starszy zapis spotkasz w dokumentacji i w istniejących projektach, dlatego warto go rozpoznawać.
Rejestracja Globalna
Jeśli komponent jest używany w wielu miejscach aplikacji (np. przycisk, ikona), możesz go zarejestrować globalnie w pliku main.js, w tej samej sekwencji zapłonu, którą poznałeś w Strefie Startowej:
1// main.js
2import { createApp } from 'vue'
3import App from './App.vue'
4import BaseButton from './components/common/BaseButton.vue'
5import BaseIcon from './components/common/BaseIcon.vue'
6
7const app = createApp(App)
8
9// Rejestracja globalna - dostępne wszędzie bez importu
10app.component('BaseButton', BaseButton)
11app.component('BaseIcon', BaseIcon)
12
13app.mount('#app')Metoda app.component() przyjmuje nazwę i komponent, a jej wywołania stoją przed mount(), tak jak wywołania app.use(). Po rejestracji globalnej komponent jest dostępny w każdym szablonie bez konieczności importowania:
1<!-- Dowolny komponent w aplikacji -->
2<template>
3 <BaseButton>Uruchom moduł</BaseButton>
4 <BaseIcon name="rocket" />
5</template>
6
7<script setup>
8// Nie trzeba importować BaseButton ani BaseIcon!
9</script>Szablon wygląda tak samo jak przy imporcie lokalnym - zniknęła tylko linia import. Wygoda ma jednak cenę, którą pokazuje tabela.
Lokalne vs Globalne - Kiedy Co Wybrać?
| Cecha | Import lokalny | Rejestracja globalna |
|---|---|---|
| Dostępność | Tylko w komponencie, który importuje | Wszędzie w aplikacji |
| Tree-shaking | Tak - nieużywane komponenty są usuwane z buildu | Nie - zawsze w bundlu |
| Czytelność | Widać zależności w <script setup> | Ukryte zależności |
| Zastosowanie | Większość komponentów | Bazowe, często używane (Base*, App*) |
Dokumentacja Vue wskazuje dwie wady rejestracji globalnej: narzędzie budujące nie usunie nieużywanego komponentu z paczki, a w dużej aplikacji trudniej prześledzić, skąd komponent pochodzi. Dlatego import lokalny traktuj jako domyślny. Globalnie rejestruj tylko komponenty bazowe używane naprawdę często - to moja rekomendacja dla całej bazy.
PascalCase vs kebab-case w Szablonie
Vue pozwala używać obu konwencji nazewnictwa w szablonach. Komponent zaimportowany jako ModuleCard możesz zapisać także jako module-card:
1<script setup>
2import ModuleCard from './ModuleCard.vue'
3import StatusBar from './StatusBar.vue'
4</script>
5
6<template>
7 <!-- PascalCase (zalecane w SFC) -->
8 <ModuleCard />
9 <StatusBar />
10
11 <!-- kebab-case (też działa) -->
12 <module-card />
13 <status-bar />
14</template>Oba zapisy wstawią te same komponenty. PascalCase jest zalecane w Single File Components (.vue), bo:
- Łatwiej odróżnić komponenty Vue od natywnych elementów HTML
<ModuleCard />to komponent,<div>to HTML- Lepsza czytelność i spójność z nazwą pliku
Wyjątek dotyczy szablonów pisanych bezpośrednio w pliku HTML: przeglądarka ignoruje tam wielkość liter, więc trzeba użyć kebab-case i pełnego znacznika zamykającego. W plikach .vue tej pułapki nie ma, a samozamykający <ModuleCard /> działa bez problemu.
W edytorze poniżej App.vue importuje trzy komponenty: StatusPanel, ControlBar i InfoCard. Usuń jeden z importów i zobacz, że jego część panelu znika z podglądu.
Zapamiętaj: komponent jest jak moduł w rejestrze stacji - import lokalny wpisuje go do jednego panelu, a app.component() do całej bazy, więc sięgaj po rejestrację globalną tylko wtedy, gdy moduł naprawdę pracuje wszędzie.
Kod do tej lekcji: App.vue
1<script setup>
2import StatusPanel from './StatusPanel.vue'
3import ControlBar from './ControlBar.vue'
4import InfoCard from './InfoCard.vue'
5
6// W <script setup> importowane komponenty sa automatycznie zarejestrowane
7// Nie trzeba ich dodawac do components: {} - Vue robi to za nas!
8</script>
9
10<template>
11 <div class="registration-lab">
12 <div class="header">
13 <h1>Rejestracja Komponentow - NOVA LAB</h1>
14 <p class="subtitle">Import i auto-rejestracja w script setup</p>
15 </div>
16
17 <div class="info-panel">
18 <h3>Importowanie komponentow</h3>
19 <p>W <strong>script setup</strong> wystarczy zaimportowac komponent - Vue automatycznie go zarejestruje</p>
20 <p>Kazdy komponent to osobny plik <strong>.vue</strong> z wlasnym template, script i style</p>
21 </div>
22
23 <div class="components-grid">
24 <StatusPanel />
25 <ControlBar />
26 <InfoCard />
27 </div>
28
29 <div class="code-note">
30 <h3>Jak to dziala?</h3>
31 <p>1. Tworzymy plik komponentu (np. StatusPanel.vue)</p>
32 <p>2. Importujemy go: import StatusPanel from './StatusPanel.vue'</p>
33 <p>3. Uzywamy w template: <StatusPanel /></p>
34 <p>To wszystko! Zadnej dodatkowej rejestracji nie potrzeba.</p>
35 </div>
36 </div>
37</template>
38
39<style scoped>
40.registration-lab {
41 background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%);
42 min-height: 100vh;
43 padding: 2rem;
44 color: #ffffff;
45 font-family: 'Courier New', monospace;
46}
47
48.header {
49 text-align: center;
50 margin-bottom: 2rem;
51 padding-bottom: 1rem;
52 border-bottom: 2px solid #00ff88;
53}
54
55.header h1 {
56 font-size: 2rem;
57 color: #00ff88;
58 text-shadow: 0 0 20px rgba(0, 255, 136, 0.5);
59 margin: 0;
60}
61
62.subtitle {
63 color: #00b4d8;
64 font-size: 1.1rem;
65 margin-top: 0.5rem;
66}
67
68.info-panel {
69 background: rgba(0, 180, 216, 0.1);
70 border: 2px solid #00b4d8;
71 border-radius: 10px;
72 padding: 1.5rem;
73 margin-bottom: 2rem;
74}
75
76.info-panel h3 {
77 color: #00b4d8;
78 margin-top: 0;
79}
80
81.info-panel strong {
82 color: #00ff88;
83}
84
85.components-grid {
86 display: grid;
87 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
88 gap: 1.5rem;
89 margin-bottom: 2rem;
90}
91
92.code-note {
93 background: rgba(0, 0, 0, 0.4);
94 border-left: 4px solid #00ff88;
95 padding: 1.5rem;
96 border-radius: 8px;
97}
98
99.code-note h3 {
100 color: #00ff88;
101 margin-top: 0;
102}
103
104.code-note p {
105 color: #00b4d8;
106 margin: 0.5rem 0;
107}
108</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 zaimportować komponent w <script setup>?
2. Jak użyć zaimportowanego komponentu w template?
To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Edytor kodu
Zaimportuj MarsModule i użyj go w App.vue.
- Układanie w pionie
Ułóż kroki importu komponentu w script setup: