Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Глобальное состояние: 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> в первом примере.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.