В разделе Искусство I повторно используемых компонентов Vue / Vuetify мы сделали компонент многократного использования, используя свойства Vue. Как только приложение становится более сложным, передача реквизита и отправка обратно родителям, бабушкам и дедушкам может быстро стать трудной для обслуживания. Vuex - это способ управления состоянием в вашем приложении Vue, поэтому давайте рассмотрим интеграцию Vuex в наш простой компонент.

Добавить Vuex в проект

[nick_pate@linux my-chip]$ yarn add vuex
yarn add v1.9.4
[1/4] Resolving packages...
[2/4] Fetching packages...
......
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ [email protected]
info All dependencies
└─ [email protected]
Done in 1.67s.

Создать структуру папок для состояния

Мы создали каталог с именем store, в нем файлы с именами: GameStoreModule.js, index.js и mutation-types.js. Давайте рассмотрим, что они делают.

mutation-types.js

GameStoreModule.js

Мы будем использовать большинство основных концепций Vuex, включая Состояние, Получатели, Действия, Мутации и Модули.

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

В конструкторе мы устанавливаем переменную класса с именем namespace и устанавливаем для нее значение true. Это включит функцию модулей Vuex и позволит нам разбить наше состояние на более мелкие модули. Используя это, мы можем инкапсулировать функциональность вместо того, чтобы иметь все состояние в глобальном пространстве имен.

В Chrome есть отличный отладчик Vue / Vuex. Обратите внимание на префикс game /. Без пространств имен все состояние было бы в глобальном контексте. Представьте, что вам нужно придумать уникальные имена для всего вашего штата. В качестве примера предположим, что мы хотели отслеживать заархивированные игры. Вы можете создать еще один класс ES6 с именем GameArchiveStoreModule. Он может содержать те же геттеры и имена переменных состояния, что и GameStoreModule, но они будут иметь префикс archive вместо game.

this.state

Определите, что мы хотим отслеживать.

this.getters

Мы можем получить доступ к нашему состоянию через геттеры. Геттеры можно использовать для вычисления вычисленных значений. В более сложных компонентах вы можете захотеть представить свое состояние иначе, чем оно хранится. Getter был бы идеальным местом для этого. Я предпочитаю всегда получать доступ к состоянию Vuex через геттеры.

this.actions

Действия - это то, что мы используем для установки состояния. Они похожи на мутации, хотя действия вызывают метод с именем commit вместо того, чтобы напрямую устанавливать состояние. Действия - это места, где вы можете обратиться к API и получить данные, а затем зафиксировать их в состоянии. Обратите внимание, что мы используем деструкцию ES6, чтобы иметь возможность использовать фиксацию в качестве вызова метода.

this.mutations

В документации Vuex говорится: «Единственный способ изменить состояние в хранилище Vuex - это совершить мутацию». Обратите внимание, что первый аргумент наших мутаций - это состояние. Второй аргумент - это то, что мы передали своими действиями. Это может быть объект, массив, строка… и т. Д.

index.js

Импортируйте наш GameStoreModule, сообщите Vue, что мы хотим использовать Vuex, и создайте новое хранилище Vuex с настроенными модулями. Имя, которое вы передадите в модуль, будет именем вашего магазина. Не забудьте открыть main.js и добавить магазин в наш экземпляр vue.

Теперь у нас есть строительные блоки. Давайте использовать это!

Помните, что наш предыдущий компонент передавал выбранные и доступные заголовки в свойства MyChip.

Давайте изменим это, чтобы использовать Vuex!

Сначала я удалил v-модель и доступные реквизиты из компонента MyChip. В строке 15 мы импортировали помощник Vuex mapActions. Сделав это, мы можем получить доступ к нашим действиям Vuex через this. Что касается методов, я использовал mapActions двумя разными способами. Первое mapActions - это то, как вы будете использовать точно определенное действие Vuex, которое мы создали в GameStoreModule.js. Во втором примере mapAction показано, как задать имя настраиваемой переменной this для определенного действия. Это полезно, когда у вас есть перекрывающиеся имена методов действия. Обратите внимание, что в обоих случаях мы получаем доступ к модулю или пространству имен game. Когда компонент монтируется, я вызываю наши действия для установки состояния вместо передачи свойств MyChip.

Теперь нам нужно изменить наш компонент MyChip, чтобы он использовал Vuex вместо того, чтобы полагаться на реквизиты. В большинстве случаев я бы не использовал Vuex в повторно используемом компоненте, потому что это нарушает принцип единой ответственности, а также объединяет два компонента. В качестве альтернативы я бы использовал геттеры в родительском компоненте в качестве реквизита для MyChip. Для демонстрации Vuex это прекрасный подход.

Вот наш предыдущий компонент MyChip.

Раздел Script будет изменен несколькими способами. Сначала мы удалим значение и доступные реквизиты. Вместо этого мы будем получать их от Vuex. Затем мы импортируем mapGetters, mapActions из Vuex и создадим вычисляемую секцию, которая генерирует наши геттеры. После этого мы добавим раздел mapActions, обновим наш метод удаления и создадим метод onChange.

Здесь следует отметить несколько моментов. Мы изменили v-модель на: value. Ранее мы использовали v-model для настройки двусторонней привязки, но это вызовет проблемы с мутацией состояния Vuex. Чтобы обрабатывать изменения, мы настраиваем метод onChange и просто устанавливаем состояние Vuex с действием.

Были сделаны!

Что дальше? Что бы вы улучшили? Может быть, создать общий базовый класс магазина? Как мы могли бы удержать MyChip от использования Vuex и сохранить его возможность повторного использования?
Подсказка: сохраните реквизиты и эмиссии в MyChip, но передайте геттеры.

Попробуйте и спасибо за чтение!

Посмотреть исходный код.