Управление состоянием в Vue.js с помощью Vuex

В большом приложении Vue вы неизбежно столкнетесь с проблемой того, что разные компоненты должны использовать одну и ту же переменную. Чтобы это работало, вам часто приходится передавать одну и ту же переменную между множеством компонентов. Переменные передаются от компонента к компоненту на всем пути вниз по дереву, что делает ваш код нечитаемым. Если вы будете продолжать это достаточно долго, вы достигнете определенного момента, когда управление состоянием станет очень сложным.

Vuex

Решением, конечно же, является Vuex. Vuex - это библиотека управления состоянием для приложений Vue.js. В центре каждого приложения Vuex находится хранилище, которое по сути представляет собой контейнер, в котором хранится состояние приложения.

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

В этой статье я покажу вам, как настроить хранилище Vuex и как вы можете использовать это хранилище в компонентах Vue. Я начну с нуля с новым проектом Vue.

Установка

Чтобы использовать Vuex в нашем приложении Vue, мы должны сначала установить его:

npm install vuex --save

Создание магазина

Структура папки

У магазина, который мы собираемся создать, будет своя папка. Итак, давайте начнем с создания store folder в src папке. Магазин может содержать несколько модулей, которые я предпочитаю хранить в отдельной папке. Создайте новую папку с именем modules в папке store, которую вы только что создали. В папке modules мы создадим еще одну папку с именем products, которая будет управлять состоянием продуктов в нашем приложении.

Индекс магазина

В папке store мы создадим файл с именем index.js. Этот файл содержит определение нашего магазина. Как видите, модули импортируются в магазин.

Модули

Все состояние вашего приложения Vue содержится внутри одного объекта. Он может стать действительно большим по мере роста вашего приложения. К счастью, Vuex позволяет разделить магазин на модули. Каждый модуль содержит собственное состояние, геттеры, действия и мутации.

В модуле есть следующие файлы:

  • index.js
  • getters.js
  • actions.js
  • mutations.js

index.js

index.js - это место, где определяется состояние модуля. Кроме того, этот файл объединяет методы получения, действия и мутации в объект, представляющий модуль.

Я предпочитаю, чтобы мои модули располагались в пространстве имен. По умолчанию все внутри модуля зарегистрировано в глобальном пространстве имен. Это позволяет нескольким модулям реагировать на одну и ту же мутацию или действие. Мне не нравится это поведение по умолчанию, поэтому я выбрал namespaced = true; в модулях. Таким образом, модули более автономны.

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

Состояние - это не что иное, как объект, который необходимо совместно использовать в приложении.

mutations.js

Файл mutations.js содержит все функции мутации. Мутации, как следует из названия, несут ответственность за мутации состояния.

Мутации - единственный способ изменить ваше состояние

В Vuex первым аргументом функции мутации всегда является объект состояния.

actions.js

Файл actions.js содержит все функции действий. Действия похожи на мутации, но они не изменяют состояние. Действия совершают мутации. Кроме того, действия могут содержать асинхронные операции.

В этом примере у нас есть два действия, каждое из которых фиксирует мутацию. Действие addProducts фиксирует мутацию addProduct, которую мы будем использовать позже.

В примере, который мы собираемся создать, мы не будем использовать действие getProducts. Я создал это действие как дополнительный (асинхронный) пример того, как может выглядеть действие. Действие getProducts отправляет запрос к API и фиксирует изменение на основе ответа.

getters.js

getters.js содержит все функции получения. Геттеры - это то же самое, что вычисляемые свойства компонента. Геттеры также имеют доступ к состоянию через первый параметр.

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

Прежде чем мы сможем начать использовать хранилище в компоненте, мы должны внедрить хранилище во все дочерние компоненты из корневого компонента. Мы делаем это в main.js, где создается наш экземпляр Vue.

Примечание.
Вы можете удалить строки 4, 5 и 7, поскольку в этом примере вам не нужны аксиомы. Если вы хотите использовать Axios, вам необходимо установить его:

npm install --save axios vue-axios

Компоненты

Чтобы продемонстрировать, как магазин работает с компонентами, мы собираемся создать три компонента в папке components:

  • ProductForm.vue
  • ProductList.vue
  • InStockList.vue

ProductForm.vue

Этот компонент имеет форму, которая отправляет в магазин действие по добавлению продукта после нажатия кнопки. Как вы можете видеть в строке 29, мы отправляем действие в магазин. Поскольку мы разместили модуль в пространстве имен, мы должны добавить к имени действия префикс имени модуля.

ProductList.vue

Компонент ProductList содержит список всех товаров, как имеющихся, так и отсутствующих. Список будет отображаться только в том случае, если список продуктов не пуст.

Обратите внимание, что переменная products поступает из объекта состояния. Для этого мы используем помощник mapState. Этот помощник генерирует для нас вычисленные функции получения.

Поскольку мы разместили модуль в пространстве имен, нам нужно передать имя модуля в качестве первого аргумента. Второй аргумент - это список свойств, для которых мы хотим создать функции получения.

Мы используем оператор распространения (…), чтобы иметь возможность смешивать локальные вычисленные свойства с объектом, который возвращает mapState.

InStockList.vue

Как и компонент ProductList, этот компонент содержит список продуктов. Разница в том, что этот компонент показывает только те товары, которые есть в наличии. Для этого он использует функцию получения inStock из магазина. Эта функция применяет фильтр к переменной products, которая находится в состоянии.

Обратите внимание, что функция mapGetters используется точно так же, как функция mapState.

Давайте посмотрим на это в действии!

Теперь, когда мы создали магазин и компоненты, пора увидеть наш код в действии.

Поскольку мы используем одно и то же свойство состояния для обоих компонентов списка, оба компонента списка должны реагировать на изменение productsproperty. Это изменение будет вызвано добавлением продукта.

Как вы можете видеть на изображении выше, добавление продукта обновляет состояние, что приводит к обновлению компонентов списка.

Вот и все! Вы только что создали хранилище Vuex, которое используется компонентами Vue. Я надеюсь, что эта статья помогла вам понять и реализовать магазины Vuex. Обязательно ознакомьтесь с другими моими сообщениями. Не стесняйтесь оставлять комментарии, если у вас есть какие-либо отзывы, вопросы или вы хотите, чтобы я написал о другой теме, связанной с Vue.

Удачного кодирования!