Kurs Vue.js · Moduł 6: Komponenty

Rejestracja i Import Komponentów

4 min czytania
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ć?

CechaImport lokalnyRejestracja globalna
DostępnośćTylko w komponencie, który importujeWszędzie w aplikacji
Tree-shakingTak - nieużywane komponenty są usuwane z builduNie - zawsze w bundlu
CzytelnośćWidać zależności w <script setup>Ukryte zależności
ZastosowanieWiększość komponentówBazowe, 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: &lt;StatusPanel /&gt;</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. 1. Jak zaimportować komponent w <script setup>?

  2. 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:

Przydatne artykuły