Cours Svelte et SvelteKit · Module 5: Liaisons
bind:this - Références DOM
Dans cette leçon5
bind:this donne accès à un élément du DOM, comme saisir le pont de Bifrost !
Utilisation de base
<script>
let inputElement;
function focusInput() {
inputElement.focus();
}
</script>
<input bind:this={inputElement} placeholder="Click the button..." />
<button onclick={focusInput}>Focus on input</button>Canvas
<script>
import { onMount } from 'svelte';
let canvas;
onMount(() => {
const ctx = canvas.getContext('2d');
// Dessine une rune
ctx.fillStyle = 'gold';
ctx.font = '48px serif';
ctx.fillText('ᚱ', 50, 60);
});
</script>
<canvas bind:this={canvas} width="200" height="100"></canvas>Audio et vidéo
<script>
let audio;
let isPlaying = $state(false);
let currentTime = $state(0);
let duration = $state(0);
function togglePlay() {
if (isPlaying) {
audio.pause();
} else {
audio.play();
}
isPlaying = !isPlaying;
}
</script>
<audio
bind:this={audio}
bind:currentTime
bind:duration
src="/horn.mp3"
></audio>
<button onclick={togglePlay}>
{isPlaying ? 'Pause' : 'Play'}
</button>
<p>Time: {Math.floor(currentTime)} / {Math.floor(duration)}</p>bind:this avec des composants
<script>
import WarriorPanel from './WarriorPanel.svelte';
let panel;
function openPanel() {
panel.open(); // Appelle une méthode du composant
}
</script>
<WarriorPanel bind:this={panel} />
<button onclick={openPanel}>Open panel</button><!-- WarriorPanel.svelte -->
<script>
let isOpen = $state(false);
export function open() {
isOpen = true;
}
export function close() {
isOpen = false;
}
</script>
{#if isOpen}
<div class="panel">
Warrior panel
<button onclick={close}>Close</button>
</div>
{/if}bind:value avec ton propre composant ($bindable)
bind: fonctionne aussi avec tes composants, mais seulement sur les props marquées avec $bindable() (tu les as découvertes à Asgard, dans le module 4). Le composant déclare une telle prop, et le parent la lie avec bind:value :
<!-- Slider.svelte -->
<script>
let { value = $bindable(50), label = '' } = $props();
</script>
<label>
{label}: {value}
<input type="range" min="0" max="100" bind:value />
</label><!-- App.svelte -->
<script>
import Slider from './Slider.svelte';
let health = $state(100);
</script>
<Slider bind:value={health} label="Santé" />
<p>Santé du guerrier : {health}</p>Déplacer le curseur modifie health dans le parent. Sans $bindable(), un tel bind:value se termine par une erreur : la prop circule alors seulement du parent vers l'enfant. Dans l'éditeur ci-dessous, Slider et TextInput fonctionnent de la même façon.
Code de cette leçon : App.svelte
<script>
// Svelte 5: $bindable() - bindable props
import Slider from './Slider.svelte';
import TextInput from './TextInput.svelte';
let health = $state(100);
let strength = $state(75);
let warriorName = $state('Ragnar');
</script>
<main class="stats-panel">
<h1>Stats Panel</h1>
<p class="subtitle">Svelte 5: $bindable() props</p>
<section>
<h2>Warrior name</h2>
<TextInput bind:value={warriorName} label="Name" />
<p>Hello, <strong>{warriorName}</strong>!</p>
</section>
<section>
<h2>Stats</h2>
<Slider
bind:value={health}
label="Health"
color="#ff4444"
/>
<Slider
bind:value={strength}
label="Strength"
color="#ffd700"
/>
</section>
<div class="preview">
<h2>{warriorName}</h2>
<div class="stat">
<span>{health}</span>
<span>{strength}</span>
</div>
<p class="total">Total power: {health + strength}</p>
</div>
</main>
<style>
.stats-panel {
font-family: 'Georgia', serif;
max-width: 500px;
margin: 0 auto;
padding: 2rem;
background: #1a0f0a;
color: #e8d5b7;
min-height: 100vh;
}
h1 {
color: #d4af37;
text-align: center;
}
.subtitle {
text-align: center;
color: #8b7355;
}
section {
background: rgba(212, 175, 55, 0.1);
border: 1px solid #d4af37;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #d4af37;
font-size: 1rem;
margin-top: 0;
}
strong {
color: #ffd700;
}
.preview {
background: rgba(255, 215, 0, 0.1);
border: 2px solid #ffd700;
border-radius: 8px;
padding: 1.5rem;
text-align: center;
}
.preview h2 {
color: #ffd700;
font-size: 1.5rem;
margin: 0;
}
.stat {
display: flex;
justify-content: center;
gap: 2rem;
margin: 1rem 0;
font-size: 1.25rem;
}
.total {
color: #b19cd9;
font-size: 1rem;
}
</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. À quoi sert bind:this ?
Tâches pratiques dans le jeu
- Éditeur de code
Complète le code pour obtenir une référence vers le canvas : onMount y dessine ensuite une rune