Dr. Nova continues: "NOVA LAB station is not one monolithic block - it's a tree of modules: the main station contains sections, sections contain rooms, and rooms contain equipment. We build Vue applications the same way - from a hierarchy of components."
Composition is a pattern of building complex interfaces from simpler, smaller components. Instead of one huge component with thousands of lines of code, we divide the UI into logical parts:
1<!-- App.vue - root of the component tree -->
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>When a component uses another component in its template, a parent-child relationship is created:
1<!-- ModuleList.vue (PARENT) -->
2<template>
3 <div class="module-list">
4 <h2>Station modules</h2>
5 <!-- ModuleCard is a CHILD of ModuleList -->
6 <ModuleCard />
7 <ModuleCard />
8 <ModuleCard />
9 </div>
10</template>
11
12<script setup>
13import ModuleCard from './ModuleCard.vue'
14</script>In this example:
ModuleList is the parentModuleCard is a childApp is the parent of ModuleList - creating a hierarchyEvery Vue application creates a component tree - a hierarchical structure starting from the root component (
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βββ StationFooterThe deeper in the tree, the more specialized the component.
App is the general structure, while NavItem is a specific menu element.Components can contain other components to any depth:
1<!-- ControlPanel.vue -->
2<template>
3 <section class="control-panel">
4 <StatusDisplay />
5 <div class="actions">
6 <ActionButton label="Launch" icon="play" />
7 <ActionButton label="Stop" 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 - another level of nesting -->
2<template>
3 <div class="status">
4 <StatusIndicator label="Energy" value="87%" color="green" />
5 <StatusIndicator label="Oxygen" value="95%" color="green" />
6 <StatusIndicator label="Temperature" value="22Β°C" color="yellow" />
7 </div>
8</template>
9
10<script setup>
11import StatusIndicator from './StatusIndicator.vue'
12</script>In the Vue component tree, data flows in specific directions:
This pattern is called one-way data flow. You'll learn the details of props and events in the next module - for now remember the directions:
1 App (data)
2 β
3 βΌ props (down)
4 ModuleList
5 β
6 βΌ props (down)
7 ModuleCard
8 β
9 β² events (up)
10 ModuleList
11 β
12 β² events (up)
13 App (reacts)