Cours Svelte et SvelteKit · Module 4: Props et événements
Props avancées
Dans cette leçon5
Rest Props
Rassemble les props restantes dans un objet :
<script>
// Extrait name et weapon, rassemble le reste dans 'rest'
let { name, weapon, ...rest } = $props();
</script>
<div class="warrior" {...rest}>
<h3>{name}</h3>
<p>Arme : {weapon}</p>
</div><!-- Utilisation - class, id et data-rank vont dans 'rest' -->
<Warrior
name="Ragnar"
weapon="Hache"
class="elite"
id="warrior-1"
data-rank="jarl"
/>Syntaxe raccourcie
Quand le nom de la variable = nom de la prop :
<script>
import Warrior from './Warrior.svelte';
let name = 'Ragnar';
let strength = 95;
</script>
<!-- Syntaxe complète -->
<Warrior name={name} strength={strength} />
<!-- Syntaxe raccourcie -->
<Warrior {name} {strength} />Props comme Snippets (Svelte 5)
Le contenu placé entre les balises d'un composant arrive dans la prop children, et tu définis des fragments nommés avec un bloc {#snippet}. Le composant les affiche avec la balise {@render} (en Svelte 4, c'était le rôle des slots, <slot />) :
<!-- Card.svelte -->
<script>
let { header, children } = $props();
</script>
<div class="card">
<header>{@render header()}</header>
<main>{@render children()}</main>
</div><!-- Utilisation -->
<Card>
{#snippet header()}
<h2>En-tête de la carte</h2>
{/snippet}
<p>Contenu de la carte</p>
</Card>Props réactives
Les props sont automatiquement réactives :
<!-- Parent.svelte -->
<script>
import Barracks from './Barracks.svelte';
let warriorCount = $state(5);
</script>
<Barracks count={warriorCount} />
<button onclick={() => warriorCount++}>Ajouter</button><!-- Barracks.svelte -->
<script>
let { count } = $props();
// count se met à jour automatiquement quand il change dans le parent !
let doubled = $derived(count * 2);
</script>
<p>Guerriers : {count}, doublés : {doubled}</p>Validation des Props à l'exécution
<script>
let { name, strength = 50 } = $props();
// Affiche strength dans la console à chaque changement (mode développement uniquement)
$inspect(strength);
$effect(() => {
if (strength < 0 || strength > 100) {
console.warn(`Force invalide : ${strength}`);
}
});
</script>Code de cette leçon : App.svelte
<script>
// Advanced props: spread {...warrior} and a callback prop
import WarriorCard from './WarriorCard.svelte';
let warriors = $state([
{ id: 1, name: 'Ragnar', role: 'Berserker', level: 45 },
{ id: 2, name: 'Lagertha', role: 'Shieldmaiden', level: 42 },
{ id: 3, name: 'Bjorn', role: 'Viking', level: 38 }
]);
function levelUp(id) {
const warrior = warriors.find(w => w.id === id);
// Deep $state: changing a field updates every card that shows it
warrior.level += 1;
}
</script>
<main class="hall">
<h1>Warriors Hall</h1>
<p>{'{...warrior}'} passes every field of the object as a prop</p>
<div class="grid">
{#each warriors as warrior (warrior.id)}
<WarriorCard {...warrior} onLevelUp={levelUp} />
{/each}
</div>
</main>
<style>
.hall {
font-family: 'Georgia', serif;
max-width: 800px;
margin: 0 auto;
padding: 2rem;
background: #1a0f0a;
color: #e8d5b7;
min-height: 100vh;
}
h1 {
color: #d4af37;
text-align: center;
}
p {
text-align: center;
color: #8b7355;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1rem;
margin-top: 2rem;
}
</style>Entrées de la documentation utilisées dans cette leçon
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Comment utiliser la syntaxe raccourcie quand le nom de la variable est identique au nom de la prop ?
2. Comment passer toutes les propriétés d'un objet en tant que props ?