Aller au contenu principal

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>
info

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>
Svelte 5 — Snippets

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>
astuce

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


Comment nomme-t-on (par convention) un composant Svelte ?


Quelle rune Svelte 5 permet de déclarer les props dans un composant ?


Comment passe-t-on une prop `nom` avec la valeur 'Alice' à un composant Carte ?


Quelle syntaxe permet d'injecter du contenu HTML dans un composant via un slot ?


Comment importe-t-on un composant Svelte dans App.svelte ?



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

Bonne pratique - Un composant par fichier

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 :


Bonne pratique - Prop booléenne avec valeur par défaut

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 :


Bonne pratique - Passer des nombres avec des accolades

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.

📌 Une solution