Composants et Props Svelte
Notions théoriques
Qu'est-ce qu'un composant ?
Un composant est un bloc d'interface réutilisable. En Svelte, chaque composant est un fichier .svelte. L'idée est de découper l'interface en pièces indépendantes :
App.svelte
├── Entete.svelte
├── CarteUtilisateur.svelte ← utilisé 3 fois avec des données différentes
└── PiedDePage.svelte
Plutôt que d'écrire trois fois le HTML d'une carte utilisateur, vous créez un composant CarteUtilisateur.svelte et l'utilisez trois fois en passant des données différentes.
Créer un composant
Créez un nouveau fichier .svelte dans src/ :
src/Carte.svelte :
<div class="carte">
<h2>Titre de la carte</h2>
<p>Description de la carte.</p>
</div>
<style>
.carte {
border: 1px solid #ccc;
padding: 1rem;
border-radius: 8px;
margin: 1rem 0;
}
</style>
Importer et utiliser un composant
Dans src/App.svelte :
<script>
import Carte from './Carte.svelte'
</script>
<main>
<Carte />
<Carte />
</main>
Les composants Svelte s'importent comme des modules ES. Par convention, le nom d'un composant commence par une majuscule (Carte, CarteProfil, Entete) pour le distinguer des éléments HTML natifs (div, p, h1).
Les props : passer des données à un composant
Les props (propriétés) permettent de passer des données depuis le composant parent vers le composant enfant.
Dans le composant enfant, on déclare les props avec la rune $props() :
<!-- src/Carte.svelte -->
<script>
let { titre, description } = $props()
</script>
<div class="carte">
<h2>{titre}</h2>
<p>{description}</p>
</div>
Dans le composant parent, on passe les valeurs comme des attributs HTML :
<!-- src/App.svelte -->
<script>
import Carte from './Carte.svelte'
</script>
<main>
<Carte titre="PHP" description="Langage de programmation côté serveur." />
<Carte titre="JavaScript" description="Langage de programmation côté navigateur." />
</main>
Props avec valeur par défaut
On peut définir une valeur par défaut pour une prop :
<script>
let { titre, description = 'Aucune description disponible.' } = $props()
</script>
Si le parent ne passe pas description, la valeur par défaut est utilisée.
Les slots : contenu enfant
Le slot permet d'injecter du contenu HTML entre les balises d'un composant :
<!-- src/Encart.svelte -->
<div class="encart">
<slot />
</div>
<!-- App.svelte -->
<Encart>
<p>Ce contenu est injecté dans le slot.</p>
</Encart>
En Svelte 5, les slots sont remplacés par les snippets. Pour une initiation, nous utilisons la syntaxe <slot /> qui reste fonctionnelle et plus simple à comprendre.
Exemple pratique
Voici une application avec un composant CarteProfil réutilisable :
src/CarteProfil.svelte :
<script>
let { nom, role, couleur = '#3578e5' } = $props()
</script>
<div class="carte" style="border-color: {couleur}">
<h3>{nom}</h3>
<span class="badge" style="background-color: {couleur}">{role}</span>
</div>
<style>
.carte {
border: 2px solid;
padding: 1rem;
border-radius: 8px;
margin: 0.5rem 0;
max-width: 300px;
}
.badge {
color: white;
padding: 0.2rem 0.6rem;
border-radius: 4px;
font-size: 0.85rem;
}
</style>
src/App.svelte :
<script>
import CarteProfil from './CarteProfil.svelte'
</script>
<main>
<h1>Équipe</h1>
<CarteProfil nom="Alice Dupont" role="Développeuse" couleur="#2e8555" />
<CarteProfil nom="Bob Martin" role="Administrateur" couleur="#e87722" />
<CarteProfil nom="Clara Leclerc" role="Designer" />
</main>
<style>
main {
padding: 2rem;
font-family: sans-serif;
}
</style>
La prop couleur a une valeur par défaut (#3578e5). Pour Clara, aucune couleur n'est passée, donc la carte utilise le bleu par défaut.
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Dans ce TP, vous allez créer un composant Produit.svelte réutilisable et l'afficher plusieurs fois avec des données différentes.
Étape 1 — Créer le projet
npm create vite@latest tp-composants --template svelte
cd tp-composants
npm install
npm run dev
En Svelte, un composant = un fichier .svelte. Ne regroupez pas plusieurs composants dans un même fichier. Cette règle facilite la navigation dans le projet et la réutilisation des composants.
Étape 2 — Créer le composant Produit
Créez src/Produit.svelte avec les props nom, prix et disponible :
Pour les props booléennes (disponible = true), définissez toujours une valeur par défaut. Cela rend le composant utilisable même si le parent oublie de passer cette prop, et documente le comportement par défaut attendu.
Étape 3 — Utiliser le composant dans App.svelte
Importez et utilisez Produit trois fois dans App.svelte :
Pour passer une valeur numérique comme prop (prix={29.99}), utilisez des accolades et non des guillemets. prix="29.99" passerait une chaîne de caractères, ce qui peut causer des bugs lors d'opérations arithmétiques.