Глобальное состояние: Alpine.store
Данные из x-data принадлежат одному компоненту. Если одни и те же данные нужны в разных частях страницы — счётчик задач в шапке и сам список в середине, — их кладут в хранилище. Alpine.store() создаёт глобальный объект с данными, а любой компонент читает и меняет его через $store.
Создание хранилища
Хранилище, как и компонент, регистрируется в обработчике alpine:init:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script>
document.addEventListener('alpine:init', () => {
Alpine.store('todos', {
items: ['Купить молоко']
});
});
</script>
<header x-data>
Задач: <span x-text="$store.todos.items.length"></span>
</header>
<main x-data>
<button @click="$store.todos.items.push('Новая задача')">Добавить</button>
</main>Шапка и кнопка — два отдельных компонента. Клик в одном меняет число в другом: оба работают с одним хранилищем todos.
Методы и геттеры
В хранилище можно держать и логику. Внутри методов this указывает на само хранилище:
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script>
document.addEventListener('alpine:init', () => {
Alpine.store('todos', {
items: [
{ id: 1, title: 'Купить молоко', done: true },
{ id: 2, title: 'Позвонить Олегу', done: false }
],
get left() {
return this.items.filter(task => !task.done).length;
},
toggle(task) {
task.done = !task.done;
}
});
});
</script>
<p x-data x-text="'Осталось: ' + $store.todos.left"></p>
<ul x-data>
<template x-for="task in $store.todos.items" :key="task.id">
<li @click="$store.todos.toggle(task)" x-text="(task.done ? '✓ ' : '') + task.title"></li>
</template>
</ul>Сверху — «Осталось: 1». Клик по задаче меняет её отметку, и число пересчитывается.
Метод init()
Если у хранилища есть метод init(), Alpine вызовет его при регистрации. Там удобно подготовить начальные данные:
// index.html, внутри обработчика alpine:init
Alpine.store('todos', {
items: [],
init() {
this.items = [{ id: 1, title: 'Купить молоко', done: false }];
}
});Хранилище в проекте с npm
В src/main.js хранилище регистрируют до Alpine.start():
// src/main.js
import Alpine from 'alpinejs';
Alpine.store('todos', {
items: []
});
Alpine.start();Из обычного JavaScript вне разметки хранилище читается так же: Alpine.store('todos').items.
Компонент или хранилище
| Данные | Где хранить |
|---|---|
| Нужны одному блоку: открыто ли меню, текст в поле | x-data |
| Нужны нескольким блокам: задачи, пользователь, тема | Alpine.store |
Частая ошибка
Обращаться к $store на элементе без x-data. Как и все директивы, x-text="$store.todos.left" работает только внутри компонента. Отдельному элементу, которому нужны лишь данные хранилища, ставьте пустой x-data, как у <header> в первом примере.