Ontwerp een Vue.js-component met dynamische sloten en scoped slots
description
Met deze prompt leer je complexe Vue.js-componenten te maken die flexibel aanpasbaar zijn via dynamische en scoped slots. Dit verhoogt de herbruikbaarheid van je componenten en maakt ze beter schaalbaar binnen grotere projecten. Het helpt je om je frontend code modulair en onderhoudbaar te houden, wat efficiënter is dan statische slotimplementaties.
prompt
Help me een Vue.js-component te ontwerpen die gebruikmaakt van dynamische sloten en scoped slots om flexibele en herbruikbare componentstructuren te creëren. Beschrijf hoe ik dynamische slotnamen kan definiëren, data kan doorgeven via scoped slots, en voorbeelden van gebrui ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een uitgebreide uitleg en voorbeeld van hoe je een Vue.js-component kunt ontwerpen die gebruikmaakt van dynamische slotnamen en scoped slots voor maximale flexibiliteit en herbruikbaarheid.
### 1. Dynamische slotnamen definiëren
In Vue.js kun je dynamische slotnamen gebruiken door gebruik te maken van de `v-slot:[naam]` syntax. Dit stelt je in staat om slotnamen op te bouwen op basis van data of props.
### 2. Data doorgeven via scoped slots
Scoped slots laten je toe om data vanuit de parent door te geven aan de child via de slot, zodat je content dynamisch en contextafhankelijk kunt maken.
### 3. Voorbeeld: Flexibele layout component
Hier is een voorbeeld van een component `FlexibleLayout.vue` dat dynamische slotnamen en scoped slots gebruikt:
```vue
<template>
<div class="layout">
<!-- Dynamische header -->
<slot :name="headerSlotName" :userData="userData"></slot>
<!-- Main content -->
<div class="content">
<slot name="main"></slot>
</div>
<!-- Dynamische footer -->
<slot :name="footerSlotName" :userData="userData"></slot>
</div>
</template>
<script>
export default {
props: {
headerSlotName: {
type: String,
default: 'header'
},
footerSlotName: {
type: String,
default: 'footer'
},
userData: {
type: Object,
default: () => ({ userName: 'Jan', userRole: 'Admin' })
}
}
}
</script>
<style>
.layout {
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
</style>
```
### 4. Gebruik van de component met dynamische slotnamen en scoped slots
In de parent component kun je de `FlexibleLayout` gebruiken en de slots dynamisch invullen:
```vue
<template>
<FlexibleLayout
:headerSlotName="'customHeader'"
:footerSlotName="'customFooter'"
:userData="{ userName: 'Jan', userRole: 'Admin' }"
>
<!-- Definieer de header slot -->
<template v-slot:customHeader="{ userData }">
<header>
<h1>Welkom, {{ userData.userName }}</h1>
<p>Rol: {{ userData.userRole }}</p>
</header>
</template>
<!-- Main content -->
<template v-slot:main>
<p>Dit is het hoofdgedeelte van de layout.</p>
</template>
<!-- Definieer de footer slot -->
<template v-slot:customFooter="{ userData }">
<footer>
<p>Footer voor {{ userData.userName }}</p>
</footer>
</template>
</FlexibleLayout>
</template>
```
### 5. Toelichting
- Je definieert de naam van de slot via props (`headerSlotName`, `footerSlotName`), die je dynamisch kunt aanpassen.
- De scoped slots krijgen de data `userData` door, zodat je de inhoud kunt personaliseren op basis van de data.
- Je kunt meerdere layout-varianten maken door eenvoudig de slotnamen te wijzigen.
### 6. Gebruiksscenario: Dashboard lay-out
Voor een dashboard met secties die aanpasbaar zijn, kun je bijvoorbeeld verschillende secties (zoals statistieken, grafieken, berichten) dynamisch invullen door verschillende slotnamen te gebruiken:
```vue
<FlexibleLayout
headerSlotName="dashboardHeader"
footerSlotName="dashboardFooter"
:userData="{ userName: 'Sara', userRole: 'Gebruiker' }"
>
<template v-slot:dashboardHeader="{ userData }">
<div class="dashboard-header">
<h2>Dashboard van {{ userData.userName }}</h2>
</div>
</template>
<template v-slot:main>
<div class="stats">
<!-- Statistieken -->
</div>
<div class="charts">
<!-- Grafieken -->
</div>
</template>
<template v-slot:dashboardFooter="{ userData }">
<div class="dashboard-footer">
<p>Gebruiker: {{ userData.userName }}, Rol: {{ userData.userRole }}</p>
</div>
</template>
</FlexibleLayout>
```
### Samenvatting
- Gebruik `v-slot:[slotnaam]` voor dynamische slotnamen.
- Geef data door via scoped slots met `:userData`.
- Pas de layout aan door slotnamen en inhoud te variëren afhankelijk van het gebruiksscenario.
Zo heb je een zeer flexibele en herbruikbare Vue.js-structuur die gemakkelijk kan worden aangepast voor verschillende layouts en inhoudsbehoeften.
provider: deepseek
model: deepseek-chat
Hier is een complete uitleg voor het maken van een flexibele Vue.js-component met dynamische slots en scoped slots:
## Basis Component Structuur
```vue
<template>
<div class="flexible-layout">
<!-- Dynamische slot voor header -->
<div v-if="$slots[headerSlotName]" class="header-section">
<slot :name="headerSlotName" :user="userData"></slot>
</div>
<!-- Main content slot -->
<div class="main-content">
<slot :user="userData"></slot>
</div>
<!-- Dynamische slot voor footer -->
<div v-if="$slots[footerSlotName]" class="footer-section">
<slot :name="footerSlotName" :user="userData"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'FlexibleLayout',
props: {
headerSlotName: {
type: String,
default: 'header'
},
footerSlotName: {
type: String,
default: 'footer'
},
userData: {
type: Object,
default: () => ({})
}
}
}
</script>
<style scoped>
.flexible-layout {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.header-section {
background: #f5f5f5;
padding: 1rem;
border-bottom: 1px solid #ddd;
}
.main-content {
flex: 1;
padding: 2rem;
}
.footer-section {
background: #333;
color: white;
padding: 1rem;
}
</style>
```
## Gebruiksvoorbeeld: Dashboard Layout
```vue
<template>
<div>
<FlexibleLayout
:header-slot-name="dynamicHeaderName"
:footer-slot-name="dynamicFooterName"
:user-data="user"
>
<!-- Dynamische header slot -->
<template #[dynamicHeaderName]="{ user }">
<div class="dashboard-header">
<h1>Welkom, {{ user.userName }}</h1>
<span class="role-badge">{{ user.userRole }}</span>
</div>
</template>
<!-- Main content (default slot) -->
<template #default="{ user }">
<div class="dashboard-content">
<h2>Dashboard Overzicht</h2>
<div class="stats">
<p>Ingelogd als: {{ user.userRole }}</p>
<!-- Meer dashboard content -->
</div>
</div>
</template>
<!-- Dynamische footer slot -->
<template #[dynamicFooterName]="{ user }">
<div class="dashboard-footer">
<p>© 2024 Bedrijfsnaam - Beheerd door {{ user.userName }}</p>
</div>
</template>
</FlexibleLayout>
</div>
</template>
<script>
import FlexibleLayout from './FlexibleLayout.vue'
export default {
components: {
FlexibleLayout
},
data() {
return {
dynamicHeaderName: 'header',
dynamicFooterName: 'footer',
user: {
userName: 'Jan',
userRole: 'Admin'
}
}
}
}
</script>
```
## Geavanceerd Voorbeeld: Conditionele Slots
```vue
<template>
<FlexibleLayout
:header-slot-name="currentView + 'Header'"
:footer-slot-name="showFooter ? 'footer' : null"
:user-data="user"
>
<!-- Conditionele header op basis van view -->
<template #dashboardHeader="{ user }">
<header class="dashboard-header">
<h1>Dashboard - {{ user.userName }}</h1>
</header>
</template>
<template #profileHeader="{ user }">
<header class="profile-header">
<h1>Profiel - {{ user.userName }}</h1>
</header>
</template>
<!-- Dynamische content gebaseerd op user role -->
<template #default="{ user }">
<div v-if="user.userRole === 'Admin'">
<AdminDashboard :user="user" />
</div>
<div v-else>
<UserDashboard :user="user" />
</div>
</template>
</FlexibleLayout>
</template>
```
## Gebruiksscenario's
### 1. Multi-tenant Dashboard
```vue
<FlexibleLayout
:header-slot-name="tenant + 'Header'"
:user-data="currentUser"
>
<template #tenantAHeader="{ user }">
<!-- Aangepaste header voor Tenant A -->
</template>
<template #tenantBHeader="{ user }">
<!-- Aangepaste header voor Tenant B -->
</template>
</FlexibleLayout>
```
### 2. Theme-able Component
```vue
<FlexibleLayout
:header-slot-name="currentTheme + 'Header'"
:footer-slot-name="currentTheme + 'Footer'"
>
<template #darkHeader>
<!-- Donkere theme header -->
</template>
<template #lightHeader>
<!-- Lichte theme header -->
</template>
</FlexibleLayout>
```
## Belangrijke Concepten
### Dynamische Slotnamen
- Gebruik `#[variabeleNaam]` syntax voor dynamische slot binding
- Slotnamen kunnen reactief zijn en wijzigen gebaseerd op state
### Scoped Slots Data Doorgeven
- Data doorgeven via `:user="userData"` in de slot definitie
- Ontvangen in parent component via `{ user }` destructurering
### Conditionele Slots
- Gebruik `v-if="$slots[slotNaam]"` om slots optioneel te maken
- Handig voor optionele component secties
Deze aanpak maakt zeer flexibele en herbruikbare componenten mogelijk die zich aanpassen aan verschillende use cases zonder de basiscomponent te wijzigen.