Dr. Nova kontynuuje: "Stacja NOVA LAB nie jest jednym monolitycznym blokiem - to drzewo modułów: stacja główna zawiera sekcje, sekcje zawierają pomieszczenia, a pomieszczenia zawierają urządzenia. Tak samo budujemy aplikacje Vue - z hierarchii komponentów."
Kompozycja to wzorzec budowania złożonych interfejsów z prostszych, mniejszych komponentów. Zamiast jednego ogromnego komponentu z tysiącem linii kodu, dzielimy UI na logiczne części:
1<!-- App.vue - korzeń drzewa komponentów -->
2<template>
3 <div class="station">
4 <StationHeader />
5 <main>
6 <ModuleList />
7 <ControlPanel />
8 </main>
9 <StationFooter />
10 </div>
11</template>
12
13<script setup>
14import StationHeader from './components/StationHeader.vue'
15import ModuleList from './components/ModuleList.vue'
16import ControlPanel from './components/ControlPanel.vue'
17import StationFooter from './components/StationFooter.vue'
18</script>Kiedy komponent używa innego komponentu w swoim szablonie, powstaje relacja rodzic-dziecko:
1<!-- ModuleList.vue (RODZIC) -->
2<template>
3 <div class="module-list">
4 <h2>Moduły stacji</h2>
5 <!-- ModuleCard to DZIECKO ModuleList -->
6 <ModuleCard />
7 <ModuleCard />
8 <ModuleCard />
9 </div>
10</template>
11
12<script setup>
13import ModuleCard from './ModuleCard.vue'
14</script>W tym przykładzie:
ModuleList jest rodzicem (parent)ModuleCard jest dzieckiem (child)App jest rodzicem ModuleList - tworzy się hierarchiaKażda aplikacja Vue tworzy drzewo komponentów - hierarchiczną strukturę zaczynającą się od komponentu głównego (
App.vue):1App
2├── StationHeader
3│ ├── Logo
4│ └── NavigationMenu
5│ ├── NavItem (Dashboard)
6│ ├── NavItem (Modules)
7│ └── NavItem (Settings)
8├── ModuleList
9│ ├── ModuleCard (Oxygen Generator)
10│ ├── ModuleCard (Plasma Core)
11│ └── ModuleCard (Water Recycler)
12├── ControlPanel
13│ ├── StatusDisplay
14│ └── ActionButtons
15└── StationFooterIm głębiej w drzewie, tym bardziej wyspecjalizowany jest komponent.
App to ogólna struktura, a NavItem to konkretny element menu.Komponenty mogą zawierać inne komponenty na dowolną głębokość:
1<!-- ControlPanel.vue -->
2<template>
3 <section class="control-panel">
4 <StatusDisplay />
5 <div class="actions">
6 <ActionButton label="Uruchom" icon="play" />
7 <ActionButton label="Zatrzymaj" icon="stop" />
8 <ActionButton label="Restart" icon="refresh" />
9 </div>
10 </section>
11</template>
12
13<script setup>
14import StatusDisplay from './StatusDisplay.vue'
15import ActionButton from './ActionButton.vue'
16</script>1<!-- StatusDisplay.vue - kolejny poziom zagnieżdżenia -->
2<template>
3 <div class="status">
4 <StatusIndicator label="Energia" value="87%" color="green" />
5 <StatusIndicator label="Tlen" value="95%" color="green" />
6 <StatusIndicator label="Temperatura" value="22°C" color="yellow" />
7 </div>
8</template>
9
10<script setup>
11import StatusIndicator from './StatusIndicator.vue'
12</script>W drzewie komponentów Vue dane przepływają w określonych kierunkach:
Ten wzorzec nazywamy jednokierunkowym przepływem danych (one-way data flow). Szczegóły props i events poznasz w następnym module - na razie zapamiętaj kierunki:
1 App (dane)
2 │
3 ▼ props (w dół)
4 ModuleList
5 │
6 ▼ props (w dół)
7 ModuleCard
8 │
9 ▲ events (w górę)
10 ModuleList
11 │
12 ▲ events (w górę)
13 App (reaguje)