bind:
D”ordinaire, les données circulent vers le bas, du parent vers ses enfants. La directive bind:
permet de faire circuler les données dans l’autre sens, de l’enfant vers le parent.
La syntaxe générale est bind:property={expression}
, où expression
est une lvalue (c-à-d une
variable ou une propriété d’objet). Lorsque l’expression est un identifiant du même nom que la
propriété, il est possible d’omettre l’expression — autrement dit ces deux écritures sont
équivalentes :
<input bind:value={value} />
<input bind:value />
Svelte crée un gestionnaire d’évènement qui met à jour la valeur liée. Si un élément a déjà un gestionnaire pour le même évènement, ce gestionnaire sera déclenché avant que la valeur liée soit mise à jour.
La plupart des liaisons sont à double sens (two-way), ce qui signifie que toute modification de la valeur va impacter l’élément est vice-versa. Quelques liaisons sont en lecture seule (readonly), ce qui signifie que les changements de valeur n’auront aucun effet sur l’élément.
Liaisons de fonction
Vous pouvez aussi utiliser bind:property={get, set}
, où get
et set
sont des fonctions, vous
permettant d’effectuer des validations et des transformations :
<input bind:value={
() => value,
(v) => value = v.toLowerCase()}
/>
Dans le cas de liaisons en lecture seule comme dimension bindings, la valeur get
doit être null
:
<div
bind:clientWidth={null, redraw}
bind:clientHeight={null, redraw}
>...</div>
Les liaisons de fonctions sont disponible à partir de Svelte version 5.9.0.
<input bind:value>
Une directive bind:value
sur un élément <input>
crée une liaison avec la propriété value
de
l’input :
<script>
let message = $state('coucou');
</script>
<input bind:value={message} />
<p>{message}</p>
Dans le cas d’un input numérique (type="number"
ou type="range"
), la valeur sera transformée en
nombre
(démo)
:
<script>
let a = $state(1);
let b = $state(2);
</script>
<label>
<input type="number" bind:value={a} min="0" max="10" />
<input type="range" bind:value={a} min="0" max="10" />
</label>
<label>
<input type="number" bind:value={b} min="0" max="10" />
<input type="range" bind:value={b} min="0" max="10" />
</label>
<p>{a} + {b} = {a + b}</p>
Si l’input est vide ou invalide (dans le cas de type="number"
), la valeur sera undefined
.
Depuis la version 5.6.0, si un <input>
faisant partie d’un formulaire possède une valeur par
défaut defaultValue
, il récupèrera cette valeur par défaut plutôt que la chaîne de caractères vide
lors de la réinitialisation du formulaire. Notez que pour le rendu initial, la valeur de la liaison
est prioritaire sauf s’il cette valeur est null
ou undefined
.
<script>
let value = $state('');
</script>
<form>
<input bind:value defaultValue="pas la string vide">
<input type="reset" value="Réinitialiser">
</form>
Utilisez les boutons de réinitialisation avec prudence, et assurez-vous que les utilisateurs et utilisatrices ne cliquent pas dessus accidentellement lorsqu’ils souhaitent soumettre le formulaire.
<input bind:checked>
Les inputs de type checkbox et radio peuvent être liés avec bind:checked
:
<label>
<input type="checkbox" bind:checked={accepted} />
Accepter les conditions générales
</label>
Depuis la version 5.6.0, si un <input>
faisant partie d’un formulaire possède une valeur par
défaut defaultChecked
, il récupèrera cette valeur par défaut plutôt que false
lors de la
réinitialisation du formulaire. Notez que pour le rendu initial, la valeur de la liaison
est prioritaire sauf s’il cette valeur est null
ou undefined
.
<script>
let checked = $state(true);
</script>
<form>
<input type="checkbox" bind:checked defaultChecked={true}>
<input type="reset" value="Réinitialiser">
</form>
<input bind:group>
Les inputs qui fonctionnent en groupe peuvent utiliser bind:group
.
<script>
let tortilla = $state('Nature');
/** @type {Array<string>} */
let fillings = $state([]);
</script>
<!-- les inputs radio groupés sont mutuellement exclusifs -->
<input type="radio" bind:group={tortilla} value="Nature" />
<input type="radio" bind:group={tortilla} value="Blé complet" />
<input type="radio" bind:group={tortilla} value="Épinards" />
<!-- les inputs checkbox groupés remplissent un tableau -->
<input type="checkbox" bind:group={fillings} value="Riz" />
<input type="checkbox" bind:group={fillings} value="Haricots" />
<input type="checkbox" bind:group={fillings} value="Fromage" />
<input type="checkbox" bind:group={fillings} value="Guacamole (extra)" />
bind:group
ne fonctionne que si les inputs sont dans le même composant Svelte.
<input bind:files>
Vous pouvez utiliser bind:files
sur les éléments <input>
de type="file"
pour obtenir une
FileList
des fichiers sélectionnés.
Lorsque vous souhaitez mettre à jour les fichiers programmatiquement, vous pouvez toujours utiliser
un objet FileList
. Actuellement les objets FileList
ne peuvent pas être construits directement,
vous aurez besoin de d’abord créer un nouvel objet
DataTransfer
et en extraire les
files
.
<script>
let files = $state();
function clear() {
files = new DataTransfer().files; // null ou undefined ne fonctionne pas
}
</script>
<label for="avatar">Envoyer une image :</label>
<input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
<button onclick={clear}>supprimer</button>
Les objets FileList
ne peuvent pas non plus être modifiés. Si vous souhaitez par ex. supprimer un
fichier de la liste, vous devez créer un nouvel objet DataTransfer
et y ajouter uniquement les
fichiers que vous souhaitez garder.
DataTransfer
peut ne pas être disponible dans certains runtimes JS de serveur. Ne pas initialiser l’état lié auxfiles
permet d’éviter de potentielles erreurs si les composants sont générés côté serveur.
<select bind:value>
Une liaison sur la valeur d’un élément <select>
correspond à la propriété value
de l’<option>
sélectionnée, ce qui peut être n’importe quelle valeur (pas uniquement des chaînes de caractères,
comme c’est normalement le cas dans le DOM).
<select bind:value={selected}>
<option value={a}>a</option>
<option value={b}>b</option>
<option value={c}>c</option>
</select>
Un élément <select multiple>
se comporte comme un groupe de checkbox. La variable liée est un
tableau ayant une entrée correspondant à la propriété value
de chaque <option>
sélectionnée.
<select multiple bind:value={fillings}>
<option value="Riz">Riz</option>
<option value="Haricots">Haricots</option>
<option value="Fromage">Fromage</option>
<option value="Guacamole (extra)">Guacamole (extra)</option>
</select>
Lorsque la valeur d’une <option>
correspond à son contenu tezte, l’attribut n’est pas nécessaire.
<select multiple bind:value={fillings}>
<option>Riz</option>
<option>Haricots</option>
<option>Fromage</option>
<option>Guacamole (extra)</option>
</select>
Vous pouvez fournir au <select>
une valeur par défaut en ajoutant l’attribut selected
à
l’<option>
(ou à plusieurs <option>
dans le cas d’un <select multiple>
) qui doit être
initialement sélectionnée. Si le <select>
fait partie d’un formulaire, il sera réinitialisé à
cette séletion initiale lors de la réinitialisation du formulaire. Notez que pour le rendu initial,
la valeur de la liaison est prioritaire sauf s’il cette valeur est undefined
.
<select bind:value={selected}>
<option value={a}>a</option>
<option value={b} selected>b</option>
<option value={c}>c</option>
</select>
<audio>
Les éléments <audio>
ont leur propre jeu de liaisons — cinq à double sens...
... et sept en lecture seule :
<audio src={clip} bind:duration bind:currentTime bind:paused></audio>
<video>
Les éléments <video>
ont les mêmes liaisons que les éléments [#audio], auxquels viennent s’ajouter
les liaisons en lecture seule
videoWidth
et
videoHeight
.
<img>
Les éléments <img>
ont deux liaisons en lecture seule :
<details bind:open>
Les éléments <details>
acceptent une liaison sur la propriété open
.
<details bind:open={isOpen}>
<summary>Comment réconforter un bug JavaScript ?</summary>
<p>En le consolant.</p>
</details>
Liaison Contenteditable
Les élément ayant l’attribut contenteditable
acceptent les liaisons suivantes :
Il y a des différences subtiles entre
innerText
ettextContent
<div contenteditable="true" bind:innerHTML={html} />
Dimensions
Tous les éléments visibles acceptent les liaisons suivantes en lecture seule, dont les valeurs sont
mesurées avec ResizeObserver
:
<div bind:offsetWidth={width} bind:offsetHeight={height}>
<Chart {width} {height} />
</div>
Les éléments
display: inline
n’ont pas de largeur ou de hauteur (sauf pour les éléments avec des dimensions “intrinsèques”, comme<img>
et<canvas>
), et ne peuvent pas être observés avecResizeObserver
. Vous aurez besoin de changer le styledisplay
de ces éléments à une autre valeur, commeinline-block
.
bind:this
bind:this={dom_node}
Pour obtenir la référence d’un noeud du DOM, utilisez bind:this
. La valeur liée sera undefined
jusqu’à ce que le composant soit monté — autrement dit, vous ne devriez vous servir de cette valeur
que dans un effet ou dans un gestionnaire d’évènement, mais pas lors de l’initialisation du
composant.
<script>
/** @type {HTMLCanvasElement} */
let canvas;
$effect(() => {
const ctx = canvas.getContext('2d');
drawStuff(ctx);
});
</script>
<canvas bind:this={canvas} />
Les composants acceptent aussi des liaisons bind:this
, vous permettant d’interagir
programmatiquement avec les instances de composant.
<ShoppingCart bind:this={cart} />
<button onclick={() => cart.empty()}> Panier vide </button>
<script>
// Tous les exports d'instance sont accessibles sur l'objet de l'instance
export function empty() {
// ...
}
</script>
<script lang="ts">
// Tous les exports d'instance sont accessibles sur l'objet de l'instance
export function empty() {
// ...
}
</script>
bind:property pour les composants
bind:property={variable}
Vous pouvez créer des liaisons avec des props de composant en utilisant la même syntaxe que pour les éléments.
<Keypad bind:value={pin} />
Même si les props Svelte sont réactives sans avoir besoin de liaison, cette réactivité est par
défaut descendante vers le composant. Utiliser bind:property
vous permet de changer la propriété
depuis l’intérieur du composant pour faire remonter sa valeur en dehors du composant.
Pour définir une propriété comme acceptant une liaison (bindable), utilisez la rune
$bindable
:
<script>
let { propEnLectureSeule, propAcceptantUneLiaison = $bindable() } = $props();
</script>
Déclarer une propriété comme bindable signifie qu’elle peut être utilisée avec bind:
, pas
qu’elle doit être utilisée avec bind:
.
Les propriétés bindables peuvent avoir des valeurs par défaut :
<script>
let { propAcceptantUneLiaison = $bindable('valeur par défaut') } = $props();
</script>
Cette valeur par défaut s’applique seulement lorsque la propriété n’est pas liée. Si la propriété
est liée et une valeur par défaut est définie, le parent se doit de fournir une valeur autre que
undefined
, sans quoi une erreur de runtime sera levée. Ceci permet d’éviter les situations où il
est difficile de comprendre quelle devrait être la bonne valeur utilisée.
Modifier cette page sur Github