We use cookies to enhance your experience on the site
CodeWorlds

Component Composition

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."

What Is Component Composition?

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>

Parent-Child Relationship

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 parent
  • Each
    ModuleCard
    is a child
  • App
    is the parent of
    ModuleList
    - creating a hierarchy

Component Tree

Every 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└── StationFooter

The deeper in the tree, the more specialized the component.

App
is the general structure, while
NavItem
is a specific menu element.

Nesting Components

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>

Data Flow in the Tree

In the Vue component tree, data flows in specific directions:

  • Downward (parent β†’ child): via props - the parent passes data to children
  • Upward (child β†’ parent): via events - the child informs the parent about events

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)
Go to CodeWorlds→