Паттерн Store

В библиотеке Petite-Vue управление состоянием приложения организуется через паттерн “Store”. Этот паттерн позволяет централизованно хранить данные, которые могут быть использованы в различных компонентах приложения, а также обеспечивает эффективное обновление состояния при изменении данных.

Что такое Store?

Store — это объект, который централизованно хранит состояние приложения. Вместо того чтобы каждый компонент имел своё собственное состояние, все данные, нуждающиеся в совместном использовании, могут быть помещены в Store. Это позволяет облегчить взаимодействие между компонентами и способствует упрощению архитектуры приложения.

Store в Petite-Vue аналогичен Store в Vue.js, но с упрощённым интерфейсом и меньшим количеством функциональных возможностей, что делает его подходящим для лёгких и быстрых проектов.

Создание Store

Для создания Store в Petite-Vue используется метод createStore. Этот метод принимает объект, который описывает состояние, методы и вычисляемые свойства.

Пример создания Store:

const store = PetiteVue.createStore({
  state: {
    count: 0
  },
  actions: {
    increment() {
      this.count++;
    }
  }
});

В приведённом примере создаётся Store, который хранит число count в своем состоянии и имеет метод increment для его увеличения.

Структура Store

Store состоит из нескольких частей:

  1. state — объект, который хранит данные приложения.
  2. actions — методы, которые могут изменять состояние.
  3. getters (необязательно) — вычисляемые свойства, которые зависят от состояния и могут быть использованы для извлечения данных в более удобном виде.

State — это основа Store, где хранятся все данные. Эти данные могут быть изменены только через действия (actions), что позволяет сохранять управляемость состоянием приложения.

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

Getters — вычисляемые свойства, которые позволяют извлекать данные, основываясь на состоянии. Getters могут быть полезны, если необходимо провести какие-либо преобразования данных перед их отображением.

Пример использования этих частей:

const store = PetiteVue.createStore({
  state: {
    count: 0
  },
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    }
  },
  getters: {
    doubledCount() {
      return this.count * 2;
    }
  }
});

Работа с состоянием из компонентов

После создания Store, его можно использовать в компонентах, управляемых Petite-Vue. Для этого достаточно использовать метод useStore, который позволяет получить доступ к состоянию и действиям Store в рамках компонента.

Пример использования Store в компоненте:

const App = {
  setup() {
    const store = PetiteVue.useStore();

    return { store };
  },
  template: `
    <div>
      <p>Счётчик: {{ store.state.count }}</p>
      <button @click="store.actions.increment">Увеличить</button>
      <button @click="store.actions.decrement">Уменьшить</button>
      <p>Удвоенный счёт: {{ store.getters.doubledCount }}</p>
    </div>
  `
};

В этом примере компонент использует данные из Store через store.state.count и обновляет состояние с помощью store.actions.increment и store.actions.decrement. Также используется getter store.getters.doubledCount для отображения удвоенного значения счётчика.

Асинхронные действия в Store

В Petite-Vue можно использовать асинхронные действия в Store для выполнения запросов к серверу или других долгих операций. Асинхронные действия работают аналогично синхронным, но их выполнение можно отложить с помощью async и await.

Пример асинхронного действия:

const store = PetiteVue.createStore({
  state: {
    user: null
  },
  actions: {
    async fetchUserData() {
      const response = await fetch('/api/user');
      this.user = await response.json();
    }
  }
});

В этом примере метод fetchUserData асинхронно загружает данные о пользователе с сервера и сохраняет их в состоянии user.

Использование Store в нескольких компонентах

Один из ключевых аспектов паттерна Store — возможность совместного использования данных между различными компонентами. Поскольку Store является глобальным, все компоненты, использующие его, будут иметь доступ к одному и тому же состоянию и смогут реагировать на его изменения.

Пример использования Store в нескольких компонентах:

const store = PetiteVue.createStore({
  state: {
    count: 0
  },
  actions: {
    increment() {
      this.count++;
    }
  }
});

const Counter = {
  setup() {
    const store = PetiteVue.useStore();
    return { store };
  },
  template: `
    <div>
      <p>Счётчик: {{ store.state.count }}</p>
      <button @click="store.actions.increment">Увеличить</button>
    </div>
  `
};

const Display = {
  setup() {
    const store = PetiteVue.useStore();
    return { store };
  },
  template: `
    <div>
      <p>Текущий счёт: {{ store.state.count }}</p>
    </div>
  `
};

В данном примере два компонента — Counter и Display — используют одно и то же состояние count из Store. При изменении счётчика в компоненте Counter, компонент Display автоматически отобразит новое значение.

Модификация состояния через действия

Одной из особенностей паттерна Store является тот факт, что все изменения состояния должны происходить через действия (actions). Это позволяет централизовать логику изменения данных, избежать непредсказуемых изменений и легко отслеживать все изменения состояния.

Пример изменения состояния через действия:

const store = PetiteVue.createStore({
  state: {
    count: 0
  },
  actions: {
    incrementBy(amount) {
      this.count += amount;
    }
  }
});

В этом примере метод incrementBy позволяет увеличивать значение счётчика на заданную величину.

Преимущества использования Store

  1. Централизованное управление состоянием. Все данные, которые могут использоваться в нескольких компонентах, хранятся в одном месте. Это упрощает работу с состоянием, так как исключается необходимость передавать данные между компонентами через пропсы.

  2. Упрощённое тестирование. Поскольку Store отделяет логику управления состоянием от компонентов, тестировать его становится проще, а также легче проверять корректность работы отдельных частей приложения.

  3. Чистота кода. Store упрощает структуру приложения, так как логику изменения состояния можно выносить в действия, а сам компонент может сосредоточиться только на представлении данных.

  4. Управление асинхронными действиями. Store упрощает работу с асинхронными запросами и обработкой данных, так как всё это можно централизовать в actions.

Ограничения и недостатки

Несмотря на все преимущества, паттерн Store также имеет свои ограничения:

  1. Невозможность глубокой вложенности. В Petite-Vue Store не поддерживает глубокую реактивность, как в Vue.js, что означает, что изменения в глубоко вложенных объектах или массивах могут не отслеживаться должным образом. Это требует дополнительных усилий для управления состоянием в таких случаях.

  2. Отсутствие официальных инструментов для разработки. В отличие от Vuex в Vue.js, в Petite-Vue отсутствуют такие инструменты, как DevTools, что усложняет отладку и мониторинг состояния приложения в процессе разработки.

  3. Ограниченная функциональность. Petite-Vue целенаправленно упрощена, что ограничивает возможности для более сложных и масштабных приложений. В больших приложениях использование только одного Store может привести к сложностям в управлении состоянием.

Паттерн Store в Petite-Vue подходит для небольших и средних приложений, где требуется простое, но эффективное управление состоянием.