$dispatch и $watch
Компоненты на странице независимы, но им нужно общаться: форма сообщает списку о новой задаче, счётчик узнаёт об удалении. Для этого $dispatch отправляет своё событие браузера. А $watch позволяет выполнить код, когда меняется конкретное свойство.
$dispatch
$dispatch('имя', данные) создаёт событие на текущем элементе. Событие всплывает вверх по дереву, и родитель ловит его обычным @имя:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{ last: '' }" @task-added="last = $event.detail.title">
<button @click="$dispatch('task-added', { title: 'Купить молоко' })">Добавить</button>
<p x-text="'Последняя задача: ' + last"></p>
</div>После клика выводится «Последняя задача: Купить молоко». Переданные данные лежат в $event.detail.
Соседние компоненты
Если компоненты не вложены друг в друга, событие до соседа не всплывёт. Тогда слушают его на всём окне модификатором .window:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<form x-data="{ title: '' }" @submit.prevent="$dispatch('task-added', { title }); title = ''">
<input x-model="title" placeholder="Новая задача">
<button>Добавить</button>
</form>
<ul x-data="{ tasks: [] }" @task-added.window="tasks.push($event.detail.title)">
<template x-for="task in tasks">
<li x-text="task"></li>
</template>
</ul>Форма и список — два отдельных компонента. Форма отправляет событие, список ловит его на window и добавляет задачу. Запись { title } — краткая форма { title: title }.
$watch
$watch('свойство', функция) вызывает функцию каждый раз, когда свойство меняется. Функция получает новое и старое значение. Обычно слежение включают в init():
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<div x-data="{
filter: 'all',
init() {
this.$watch('filter', (value, oldValue) => {
console.log('Фильтр:', oldValue, '→', value);
});
}
}">
<select x-model="filter">
<option value="all">Все</option>
<option value="active">Активные</option>
<option value="done">Выполненные</option>
</select>
</div>Выберите «Активные» — в консоли появится «Фильтр: all → active». При запуске функция не вызывается, только при изменении.
$watch или x-effect
$watch | x-effect | |
|---|---|---|
| За чем следит | За одним названным свойством | За всем, что прочитано в выражении |
| Запуск при старте | Нет | Да |
| Старое значение | Есть | Нет |
Частая ошибка
Называть событие в camelCase: $dispatch('taskAdded') и @taskAdded. HTML переводит имена атрибутов в нижний регистр, и Alpine слушает событие taskadded, которое никто не отправляет. Называйте события через дефис: task-added.