x-data и состояние компонента
Директива x-data превращает обычный элемент в компонент Alpine. Её значение — объект JavaScript с данными компонента, или состоянием. Когда данные меняются, Alpine сам обновляет всё, что от них зависит на странице. Такие данные называют реактивными.
Данные
Код примеров этого курса лежит в <body> файла index.html. Начнём список дел с одного поля:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ title: 'Мои дела' }">
<h2 x-text="title"></h2>
</div>Под примером появляется заголовок «Мои дела». Свойство title доступно всем директивам внутри <div>.
Методы
В объект можно положить функции. Внутри метода данные компонента доступны через this:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{
tasks: ['Купить молоко', 'Позвонить Олегу'],
addTask() {
this.tasks.push('Новая задача');
console.log(this.tasks.length);
}
}">
<button x-on:click="addTask()">Добавить</button>
<p x-text="tasks.join(', ')"></p>
</div>Каждое нажатие добавляет строку в массив: текст под кнопкой удлиняется, а в консоли под примером выводится новое число задач — 3, 4 и так далее. Alpine замечает и присваивание, и вызов push().
Геттеры
Значение, которое вычисляется из других данных, оформляют геттером — методом со словом get:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{
tasks: ['Купить молоко', 'Позвонить Олегу'],
get count() {
return this.tasks.length;
}
}">
<p>Задач: <span x-text="count"></span></p>
</div>Выводится «Задач: 2». Геттер пересчитывается сам, когда меняется массив tasks.
Вложенные компоненты
Компонент внутри компонента видит данные внешнего. Если имена совпадают, побеждает ближайший:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ owner: 'Анна', title: 'Работа' }">
<div x-data="{ title: 'Дом' }">
<p x-text="owner + ': ' + title"></p>
</div>
</div>На странице — «Анна: Дом». Пустой x-data без значения тоже допустим: он нужен, когда директивы на элементе не используют данные.
Частая ошибка
Писать в x-data стрелочные функции в качестве методов:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ count: 0, add: () => this.count++ }">
<button x-on:click="add()">+1</button>
<span x-text="count"></span>
</div>У стрелочной функции нет своего this, поэтому число не меняется. Пишите методы в краткой форме add() { this.count++ }.