Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds

Zaawansowane wzorce Slots

Teraz gdy znasz wszystkie narzędzia magazynu modułów NOVA LAB, zobaczmy jak je łączyć w zaawansowane wzorce - jak kompletny system logistyczny stacji.

Renderless Components

Renderless component to komponent który nie ma własnego template - dostarcza tylko logikę przez scoped slot. Rodzic ma pełną kontrolę nad renderowaniem.

1<!-- MissionTimer.vue (renderless) -->
2<script setup>
3import { ref, onMounted, onUnmounted } from 'vue'
4
5const count = ref(0)
6const isRunning = ref(false)
7let interval = null
8
9const start = () => {
10  if (!isRunning.value) {
11    isRunning.value = true
12    interval = setInterval(() => count.value++, 1000)
13  }
14}
15
16const stop = () => {
17  isRunning.value = false
18  clearInterval(interval)
19}
20
21const reset = () => {
22  count.value = 0
23  stop()
24}
25
26onUnmounted(() => clearInterval(interval))
27</script>
28
29<template>
30  <slot
31    :count="count"
32    :isRunning="isRunning"
33    :start="start"
34    :stop="stop"
35    :reset="reset"
36  />
37</template>
38
39<!-- Użycie z dowolnym UI -->
40<MissionTimer v-slot="{ count, isRunning, start, stop, reset }">
41  <div class="timer">
42    <h2>{{ count }}s</h2>
43    <button v-if="!isRunning" @click="start">Start</button>
44    <button v-else @click="stop">Pause</button>
45    <button @click="reset">Reset</button>
46  </div>
47</MissionTimer>

Dynamic Slot Names

Nazwy slotów mogą być dynamiczne:

1<script setup>
2import { ref } from 'vue'
3const activeSection = ref('header')
4</script>
5
6<template>
7  <StationPanel>
8    <template v-slot:[activeSection]>
9      <p>Dynamic content for {{ activeSection }}</p>
10    </template>
11  </StationPanel>
12</template>

useSlots()

Sprawdzanie jakie sloty zostały przekazane:

1<script setup>
2import { useSlots } from 'vue'
3
4const slots = useSlots()
5
6// Sprawdź czy slot istnieje
7const hasHeader = !!slots.header
8const hasFooter = !!slots.footer
9</script>
10
11<template>
12  <div class="panel">
13    <header v-if="slots.header">
14      <slot name="header" />
15    </header>
16    <main>
17      <slot />
18    </main>
19    <footer v-if="slots.footer">
20      <slot name="footer" />
21    </footer>
22  </div>
23</template>

Slot Forwarding

Komponent pośredni może przekazywać sloty dalej w dół:

1<!-- Wrapper.vue -->
2<template>
3  <InnerComponent>
4    <template v-for="(_, name) in $slots" #[name]="slotProps">
5      <slot :name="name" v-bind="slotProps || {}" />
6    </template>
7  </InnerComponent>
8</template>

Kiedy użyć którego wzorca?

| Wzorzec | Kiedy użyć | |---------|-----------| | Props | Proste dane (string, number, boolean) | | Default slot | Wstrzyknięcie dowolnego HTML | | Named slots | Wiele sekcji do wypełnienia | | Scoped slots | Rendering zależny od danych dziecka | | Renderless | Tylko logika, pełna kontrola UI | | Dynamic components | Przełączanie między komponentami | | Teleport | Renderowanie poza hierarchią DOM | | Async + Suspense | Lazy loading ciężkich komponentów |

Vai a CodeWorlds