Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

События и функции-обработчики

Событие — сигнал от браузера: пользователь нажал кнопку, ввёл текст, отправил форму. В Svelte 5 обработчик события — обычный атрибут элемента с именем on + название события: onclick, oninput, onsubmit. В него передают функцию.

Обработчик клика

<!-- src/routes/+page.svelte -->
<script>
  let count = $state(0);
 
  function handleClick() {
    count++;
  }
</script>
 
<button onclick={handleClick}>Нажато: {count}</button>

Каждый клик вызывает handleClick, и число на кнопке растёт. Передают саму функцию — без скобок. Если нужно передать аргумент, используйте стрелочную функцию: onclick={() => remove(todo.id)}.

Объект события

Обработчик получает объект события — тот же, что и в обычном JavaScript. У формы с его помощью отменяют перезагрузку страницы:

<!-- src/routes/+page.svelte -->
<script>
  let todos = $state([]);
 
  function addTodo(event) {
    event.preventDefault();
    const data = new FormData(event.currentTarget);
    todos.push({ id: Date.now(), text: data.get('text'), done: false });
    event.currentTarget.reset();
  }
</script>
 
<form onsubmit={addTodo}>
  <input name="text" placeholder="Новая задача" />
  <button>Добавить</button>
</form>
 
<p>Задач: {todos.length}</p>

Введите текст и нажмите Enter или кнопку — счётчик вырастет, а поле очистится. Модификаторов вроде |preventDefault из Svelte 4 больше нет: всё делается внутри функции.

Функция в свойстве

Дочерний компонент не меняет чужие данные, а сообщает родителю о событии. Для этого родитель передаёт ему функцию как обычное свойство. По соглашению имя такого свойства тоже начинают с on:

<!-- src/lib/components/TodoItem.svelte -->
<script>
  let { todo, ontoggle, ondelete } = $props();
</script>
 
<li>
  <input type="checkbox" checked={todo.done} onchange={() => ontoggle(todo.id)} />
  {todo.text}
  <button onclick={() => ondelete(todo.id)}>Удалить</button>
</li>

Компонент только вызывает полученные функции и передаёт им id задачи.

Использование в родителе

<!-- src/routes/+page.svelte -->
<script>
  import TodoItem from '$lib/components/TodoItem.svelte';
 
  let todos = $state([
    { id: 1, text: 'Купить хлеб', done: false },
    { id: 2, text: 'Позвонить Олегу', done: false }
  ]);
 
  function toggle(id) {
    const todo = todos.find((t) => t.id === id);
    todo.done = !todo.done;
  }
 
  function remove(id) {
    todos = todos.filter((t) => t.id !== id);
  }
</script>
 
<ul>
  {#each todos as todo (todo.id)}
    <TodoItem {todo} ontoggle={toggle} ondelete={remove} />
  {/each}
</ul>

Щелчок по чекбоксу меняет статус задачи в массиве родителя, кнопка «Удалить» убирает строку. Данные хранятся и меняются в одном месте — в +page.svelte.

Частая ошибка

Вызвать функцию вместо того, чтобы передать её:

<!-- src/lib/components/TodoItem.svelte: неправильно -->
<button onclick={remove(todo.id)}>Удалить</button>

Здесь remove выполнится сразу при выводе разметки и удалит задачу, а в onclick попадёт результат вызова. Оборачивайте вызов с аргументами в стрелочную функцию: onclick={() => remove(todo.id)}.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.