Encodera

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

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

Оглавление

Списки: блок each

Чтобы вывести на странице массив — список задач, статей, товаров, — в Svelte используют блок {#each}. Он повторяет кусок разметки для каждого элемента массива.

Блок each

<!-- src/routes/+page.svelte -->
<script>
  let todos = $state([
    { id: 1, text: 'Купить хлеб', done: false },
    { id: 2, text: 'Позвонить Олегу', done: true },
    { id: 3, text: 'Написать отчёт', done: false }
  ]);
</script>
 
<ul>
  {#each todos as todo}
    <li>{todo.text}</li>
  {/each}
</ul>

На странице появится список из трёх пунктов. Запись todos as todo значит: «для каждого элемента массива todos назови его todo».

Индекс

Вторым именем через запятую можно получить номер элемента, начиная с нуля:

<!-- src/routes/+page.svelte: только разметка, script прежний -->
<ul>
  {#each todos as todo, i}
    <li>{i + 1}. {todo.text}</li>
  {/each}
</ul>

Пункты получат номера «1.», «2.», «3.». Разметка остаётся в том же файле src/routes/+page.svelte, блок <script> не меняется.

Ключ

Если элементы добавляются, удаляются или меняются местами, Svelte должен понимать, какой пункт какому объекту соответствует. Для этого в круглых скобках указывают ключ — уникальное значение элемента, обычно id:

<!-- src/routes/+page.svelte: только разметка, script прежний -->
<ul>
  {#each todos as todo (todo.id)}
    <li>
      <input type="checkbox" checked={todo.done} />
      {todo.text}
    </li>
  {/each}
</ul>

С ключом Svelte при удалении задачи уберёт именно её элемент, а остальные оставит нетронутыми — вместе с отметками, фокусом и анимациями. Указывайте ключ всегда, когда список может меняться.

Пустой список

Ветка выводится, если массив пуст:

<script>
  let todos = $state([]);
</script>
 
<ul>
  {#each todos as todo (todo.id)}
    <li>{todo.text}</li>
  {:else}
    <li>Задач пока нет</li>
  {/each}
</ul>

Пока массив пуст, в списке виден пункт «Задач пока нет».

Деструктуризация

Свойства элемента можно сразу разобрать в переменные:

<!-- src/routes/+page.svelte: только разметка, script прежний -->
{#each todos as { id, text, done } (id)}
  <li>{text} {done ? '(готово)' : ''}</li>
{/each}

Это удобно, когда объект большой, а нужны два-три поля.

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

Использовать индекс в качестве ключа: {#each todos as todo, i (i)}. При удалении первой задачи все остальные сдвинутся, их индексы изменятся, и Svelte решит, что изменились сами элементы. Отметки чекбоксов и введённый текст «перепрыгнут» на соседние строки. В качестве ключа берите постоянный id элемента.

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

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