Управление состоянием

Muuri — это библиотека JavaScript для динамических сеток с возможностью перетаскивания, сортировки и анимации элементов. Одним из ключевых аспектов работы с Muuri является управление состоянием сетки, то есть контроль за расположением, порядком и видимостью элементов, а также возможность сохранения и восстановления этих данных.


Основные методы управления состоянием

1. Получение состояния сетки

Muuri предоставляет метод getItems() для получения текущих элементов сетки:

const items = grid.getItems();

Каждый элемент возвращается в виде объекта Muuri.Item, который содержит методы для управления положением, размером и видимостью элемента.

Для сохранения состояния сетки в виде порядка элементов используется метод getItems().map(item => item.getElement().dataset.id):

const order = grid.getItems().map(item => item.getElement().dataset.id);

Это позволяет сохранить последовательность элементов для последующего восстановления.


2. Сохранение и восстановление порядка

Muuri не хранит порядок элементов автоматически, поэтому часто используется следующая логика:

// Сохранение порядка
const savedOrder = grid.getItems().map(item => item.getElement().dataset.id);

// Восстановление порядка
const items = grid.getItems();
items.sort((a, b) => {
  return savedOrder.indexOf(a.getElement().dataset.id) - savedOrder.indexOf(b.getElement().dataset.id);
});
grid.sort(items, { layout: 'instant' });
  • sort — метод для сортировки элементов в сетке.
  • Параметр { layout: 'instant' } позволяет мгновенно применить порядок без анимации.

Работа с видимостью элементов

1. Скрытие и показ элементов

Методы hide() и show() управляют видимостью элементов:

const itemsToHide = grid.getItems().filter(item => item.getElement().classList.contains('hidden'));
grid.hide(itemsToHide, { layout: 'fade', duration: 300 });

const itemsToShow = grid.getItems().filter(item => item.getElement().classList.contains('visible'));
grid.show(itemsToShow, { layout: 'fade', duration: 300 });
  • layout задаёт тип анимации перестроения сетки.
  • duration управляет длительностью анимации.

2. Фильтрация элементов

Для управления состоянием на основе критериев используется метод filter():

grid.filter(item => item.getElement().dataset.category === 'featured', {
  layout: {
    duration: 400,
    easing: 'ease-in-out'
  }
});
  • filter позволяет отображать только элементы, удовлетворяющие условию.
  • Остальные элементы временно скрываются, но остаются частью сетки и могут быть показаны повторно.

Сохранение позиции элементов

Muuri позволяет получать текущие позиции элементов для последующего восстановления:

const positions = grid.getItems().map(item => {
  const el = item.getElement();
  return {
    id: el.dataset.id,
    x: item.getPosition().x,
    y: item.getPosition().y
  };
});

Для восстановления положения можно использовать метод move():

positions.forEach(pos => {
  const item = grid.getItems().find(i => i.getElement().dataset.id === pos.id);
  item.move(pos.x, pos.y);
});
grid.refreshItems().layout();
  • refreshItems() обновляет информацию о размере и положении элементов.
  • layout() перестраивает сетку с анимацией.

Работа с событиями изменения состояния

Muuri предоставляет богатый набор событий для отслеживания изменений:

  • move — срабатывает при перемещении элемента.
  • dragEnd — при завершении перетаскивания.
  • filter — при фильтрации элементов.
  • sort — при изменении порядка.

Пример подписки на события:

grid.on('dragEnd', () => {
  const order = grid.getItems().map(item => item.getElement().dataset.id);
  console.log('Новый порядок элементов:', order);
});

Использование событий позволяет синхронизировать состояние сетки с внешними данными, например, сохранять порядок на сервере или в localStorage.


Оптимизация управления состоянием

  1. Групповое обновление элементов — лучше скрывать, показывать или сортировать сразу массив элементов, чем делать это по одному.
  2. Использование layout() с параметром { queue: true } — позволяет объединять несколько операций в одну анимацию.
  3. Минимизация перерендеров — перед массовыми изменениями рекомендуется использовать grid.suspendLayout() и grid.resumeLayout():
grid.suspendLayout();
items.forEach(item => item.hide());
grid.resumeLayout();

Это существенно улучшает производительность при работе с большими сетками.


Синхронизация с внешним состоянием

Muuri удобно интегрировать с React, Vue или любыми другими фреймворками. Основные подходы:

  • Сохранение состояния в объекте или массиве — для передачи его в компонент.
  • Восстановление состояния при обновлении — сортировка, фильтрация и восстановление позиций элементов.
  • Использование событий Muuri для реагирования на изменения состояния и синхронизации с UI.

Управление состоянием в Muuri сочетает в себе контроль порядка, видимости и позиции элементов, а также синхронизацию с внешними данными через события и методы API. Такой подход позволяет строить интерактивные и динамические сетки с полной возможностью сохранения и восстановления состояния в любой момент.