В разделе Искусство 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, но передайте геттеры.
Попробуйте и спасибо за чтение!
Посмотреть исходный код.