Привязки: bind
Привязка (binding) связывает значение элемента формы с переменной в обе стороны: пользователь вводит текст — переменная меняется, код меняет переменную — меняется поле. Это короче, чем вручную писать атрибут value и обработчик oninput.
bind:value
<!-- src/routes/+page.svelte -->
<script>
let text = $state('');
</script>
<input bind:value={text} placeholder="Новая задача" />
<p>Вы вводите: {text}</p>
<button onclick={() => (text = '')}>Очистить</button>Абзац повторяет каждую введённую букву, а кнопка «Очистить» стирает и переменную, и текст в поле. Привязывайте значение к переменной из $state — иначе изменения не дойдут до остальной разметки.
Числа
Для полей type="number" и type="range" Svelte сам превращает строку в число:
<script>
let priority = $state(1);
</script>
<input type="number" bind:value={priority} min="1" max="5" />
<p>Приоритет × 2 = {priority * 2}</p>Введите 3 — внизу появится 6, а не строка «33».
bind:checked
Чекбокс привязывают к логическому значению:
<!-- src/routes/+page.svelte -->
<script>
let todos = $state([
{ id: 1, text: 'Купить хлеб', done: false },
{ id: 2, text: 'Позвонить Олегу', done: true }
]);
let remaining = $derived(todos.filter((t) => !t.done).length);
</script>
{#each todos as todo (todo.id)}
<label>
<input type="checkbox" bind:checked={todo.done} />
{todo.text}
</label>
{/each}
<p>Осталось: {remaining}</p>Щелчок по чекбоксу сразу меняет todo.done в массиве, и счётчик «Осталось» пересчитывается. Обработчик onchange здесь не нужен.
bind:this
bind:this кладёт в переменную сам DOM-элемент. Это нужно, когда к элементу надо обратиться напрямую — например, поставить в поле курсор:
<script>
let input;
$effect(() => {
input.focus();
});
</script>
<input bind:this={input} placeholder="Новая задача" />После открытия страницы курсор уже стоит в поле. Элемент появляется в переменной только после вывода разметки, поэтому обращаются к нему в $effect или в обработчиках, а не в начале <script>.
Привязка к свойству компонента
Чтобы родитель мог написать bind: на вашем компоненте, свойство помечают руной $bindable:
<!-- src/lib/components/TodoInput.svelte -->
<script>
let { value = $bindable('') } = $props();
</script>
<input bind:value placeholder="Новая задача" />Теперь в src/routes/+page.svelte можно написать <TodoInput bind:value={text} />, и переменная text родителя будет меняться при вводе. Запись bind:value без скобок — сокращение для bind:value={value}.
Частая ошибка
Использовать value={text} вместо bind:value={text}. Поле покажет начальное значение, но при вводе переменная не изменится, и всё, что от неё зависит, останется прежним. Атрибут передаёт значение в одну сторону, bind: — в обе.