Usamos cookies para mejorar tu experiencia en el sitio
CodeWorlds

Scoped Slots

W NOVA LAB system inwentaryzacji przekazuje dane o każdym module cargo, ale to operator decyduje jak je wyświetlić - lista, tabela, karty. Scoped slots to mechanizm przekazywania danych z dziecka do rodzica przez slot.

Problem

Zwykłe sloty dają rodzicowi kontrolę nad wyglądem, ale co jeśli dziecko ma dane, które rodzic powinien użyć? Na przykład, dziecko iteruje po liście i chce dać rodzicowi kontrolę nad renderowaniem każdego elementu.

Przekazywanie danych przez Slot

Dziecko przekazuje dane jako atrybuty na tagu

<slot>
:

1<!-- ModuleList.vue (dziecko) -->
2<script setup>
3import { ref } from 'vue'
4const items = ref([
5  { id: 1, name: 'Oxygen Tank', status: 'loaded' },
6  { id: 2, name: 'Water Filter', status: 'pending' },
7  { id: 3, name: 'Solar Cell', status: 'damaged' }
8])
9</script>
10
11<template>
12  <div class="module-list">
13    <div v-for="item in items" :key="item.id">
14      <slot :item="item" :index="item.id">
15        <!-- Fallback: proste renderowanie -->
16        <p>{{ item.name }}</p>
17      </slot>
18    </div>
19  </div>
20</template>

Odbieranie danych w rodzicu

Rodzic używa

v-slot
lub
#default
z argumentem:

1<template>
2  <!-- Pełna składnia -->
3  <ModuleList v-slot="slotProps">
4    <div class="card">
5      <h3>{{ slotProps.item.name }}</h3>
6      <span>{{ slotProps.item.status }}</span>
7    </div>
8  </ModuleList>
9
10  <!-- Z destrukturyzacją -->
11  <ModuleList v-slot="{ item, index }">
12    <div class="card">
13      <h3>#{{ index }}: {{ item.name }}</h3>
14      <span :class="item.status">{{ item.status }}</span>
15    </div>
16  </ModuleList>
17</template>

Named Scoped Slots

Scoped slots działają też z named slots:

1<!-- DataTable.vue -->
2<template>
3  <table>
4    <thead>
5      <tr>
6        <slot name="header">
7          <th>Name</th>
8          <th>Status</th>
9        </slot>
10      </tr>
11    </thead>
12    <tbody>
13      <tr v-for="item in items" :key="item.id">
14        <slot name="row" :item="item">
15          <td>{{ item.name }}</td>
16          <td>{{ item.status }}</td>
17        </slot>
18      </tr>
19    </tbody>
20  </table>
21</template>
22
23<!-- Rodzic -->
24<DataTable>
25  <template #header>
26    <th>Module Name</th>
27    <th>Current Status</th>
28    <th>Actions</th>
29  </template>
30
31  <template #row="{ item }">
32    <td>{{ item.name }}</td>
33    <td>{{ item.status }}</td>
34    <td><button>Inspect</button></td>
35  </template>
36</DataTable>
Ir a CodeWorlds