We use cookies to enhance your experience on the site
CodeWorlds

Dynamic Components

The NOVA LAB module transport system allows you to connect different panels to the same station slot - an oxygen panel, water panel, or energy panel. Vue has a dynamic components mechanism - a special

<component>
element with the
:is
attribute.

Basic Syntax

1<script setup>
2import { ref, shallowRef } from 'vue'
3import OxygenPanel from './OxygenPanel.vue'
4import WaterPanel from './WaterPanel.vue'
5import SolarPanel from './SolarPanel.vue'
6
7const tabs = { OxygenPanel, WaterPanel, SolarPanel }
8const currentTab = shallowRef(OxygenPanel)
9</script>
10
11<template>
12  <div class="station">
13    <nav>
14      <button
15        v-for="(comp, name) in tabs"
16        :key="name"
17        @click="currentTab = comp"
18      >
19        {{ name }}
20      </button>
21    </nav>
22
23    <component :is="currentTab" />
24  </div>
25</template>

We use

shallowRef
instead of
ref
for components because we don't need deep reactivity on the component object.

KeepAlive

By default, switching a component destroys the old one and creates a new one. If you want to preserve state (e.g., form data), use

<KeepAlive>
:

1<template>
2  <KeepAlive>
3    <component :is="currentTab" />
4  </KeepAlive>
5</template>

Now the component is cached - when you return to it, its state is preserved.

KeepAlive - include and exclude

Control which components to cache:

1<template>
2  <!-- Only these components -->
3  <KeepAlive :include="['OxygenPanel', 'WaterPanel']">
4    <component :is="currentTab" />
5  </KeepAlive>
6
7  <!-- All except these -->
8  <KeepAlive :exclude="['HeavyModule']">
9    <component :is="currentTab" />
10  </KeepAlive>
11
12  <!-- Cache limit (LRU) -->
13  <KeepAlive :max="5">
14    <component :is="currentTab" />
15  </KeepAlive>
16</template>

Lifecycle Hooks with KeepAlive

Cached components have additional hooks:

1<script setup>
2import { onActivated, onDeactivated } from 'vue'
3
4onActivated(() => {
5  console.log('Panel activated (visible)')
6  // Refresh data, resume timers
7})
8
9onDeactivated(() => {
10  console.log('Panel deactivated (hidden)')
11  // Stop timers, save state
12})
13</script>

Props on Dynamic Components

You can pass props to dynamic components:

1<template>
2  <component
3    :is="currentTab"
4    :station="stationData"
5    @alert="handleAlert"
6  />
7</template>
Go to CodeWorlds