x-for и ключи
Директива x-for повторяет кусок разметки для каждого элемента массива. Так выводят списки: задачи, товары, комментарии. Когда массив меняется, Alpine добавляет и убирает элементы на странице сам.
Простой список
Как и x-if, директива x-for ставится на <template>. Значение записывается в форме элемент in массив:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<ul x-data="{ tasks: ['Купить молоко', 'Позвонить Олегу', 'Оплатить интернет'] }">
<template x-for="task in tasks">
<li x-text="task"></li>
</template>
</ul>На странице список из трёх пунктов. Переменная task по очереди принимает каждое значение массива и видна внутри <template>.
Индекс
Чтобы получить номер элемента, перечислите две переменные в скобках:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<ul x-data="{ tasks: ['Купить молоко', 'Позвонить Олегу'] }">
<template x-for="(task, index) in tasks">
<li x-text="(index + 1) + '. ' + task"></li>
</template>
</ul>Пункты выводятся с номерами: «1. Купить молоко», «2. Позвонить Олегу».
Ключи
Если элементы списка могут удаляться или переставляться, у каждого должен быть ключ — уникальное значение, по которому Alpine узнаёт элемент. Ключ задаётся атрибутом :key на <template>. Обычно это id объекта:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<ul x-data="{
tasks: [
{ id: 1, title: 'Купить молоко' },
{ id: 2, title: 'Позвонить Олегу' },
{ id: 3, title: 'Оплатить интернет' }
],
remove(id) {
this.tasks = this.tasks.filter(task => task.id !== id);
}
}">
<template x-for="task in tasks" :key="task.id">
<li>
<span x-text="task.title"></span>
<button @click="remove(task.id)">Удалить</button>
</li>
</template>
</ul>Кнопка «Удалить» убирает свою задачу: метод remove() оставляет в массиве все задачи, кроме выбранной, и Alpine удаляет нужный пункт. Запись :key — сокращение для x-bind:key, о x-bind будет следующий урок.
Диапазон чисел
Вместо массива можно указать число — тогда переменная пробегает значения от 1 до него:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data>
<template x-for="page in 5">
<button x-text="page"></button>
</template>
</div>Появляются пять кнопок с номерами от 1 до 5 — заготовка для постраничной навигации.
Частая ошибка
Использовать индекс в качестве ключа: :key="index". После удаления первой задачи вторая получает индекс 0, и Alpine считает её той же, что была удалена. Состояние элементов — введённый текст, отметка в чекбоксе — может достаться не той строке. Берите в ключ постоянный id, а внутри <template> держите один корневой элемент.