x-init и x-effect
Иногда код нужно выполнить не по событию, а сам по себе: при появлении компонента на странице или каждый раз, когда меняются данные. Для первого случая есть x-init, для второго — x-effect.
x-init
Выражение в x-init выполняется один раз, когда Alpine запускает элемент:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ today: '' }" x-init="today = new Date().toLocaleDateString('ru-RU')">
<p>Дела на <span x-text="today"></span></p>
</div>В заголовке списка появляется сегодняшняя дата. Форматирование дат разбиралось в уроке «Форматирование: Intl» учебника.
Метод init()
Если в данных компонента есть метод init(), Alpine вызовет его сам при запуске компонента. Это удобнее, чем длинный x-init, когда кода много:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{
tasks: [],
init() {
this.tasks = ['Купить молоко', 'Позвонить Олегу'];
console.log('Компонент запущен, задач:', this.tasks.length);
}
}">
<p x-text="tasks.join(', ')"></p>
</div>На странице — две задачи, в консоли под примером — «Компонент запущен, задач: 2». Позже в init() будут загружаться данные с сервера.
x-effect
Выражение в x-effect выполняется сразу и затем повторяется каждый раз, когда меняются данные, которые оно читает. Alpine сам отслеживает, какие свойства использованы:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ tasks: ['Купить молоко'] }" x-effect="console.log('Задач:', tasks.length)">
<button @click="tasks.push('Новая задача')">Добавить</button>
</div>В консоли сразу появляется «Задач: 1», а каждый клик печатает новое число. Если бы выражение не читало tasks, оно выполнилось бы только один раз.
Что выбрать
| Задача | Директива |
|---|---|
| Подготовить данные при запуске | x-init или метод init() |
| Загрузить данные с сервера | Метод init() |
| Повторять действие при каждом изменении данных | x-effect |
| Следить за одним конкретным свойством | $watch, урок о нём будет позже |
Частая ошибка
Ждать, что x-init повторится при изменении данных:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ tasks: ['Купить молоко'] }" x-init="console.log('Задач:', tasks.length)">
<button @click="tasks.push('Новая задача')">Добавить</button>
</div>В консоли одна строка «Задач: 1», и клики ничего к ней не добавляют: x-init выполняется только при запуске. Когда действие должно следовать за данными, используйте x-effect.