Ознакомьтесь с полным видеокурсом:

Https://www.udemy.com/course/complete-vuejs-3-course/?referralCode=75F591E320BC4EA22188

Приложение Vue состоит из ряда вложенных компонентов. У нас есть один корневой компонент на самой внешней стороне. В него вложено ноль или несколько дочерних компонентов. Каждый дочерний компонент может иметь свои собственные дочерние компоненты.

Чтобы отправить данные внутрь, то есть от родительского компонента к его дочернему компоненту, мы используем props. Дочерний компонент может собирать информацию от пользователей и, следовательно, должен отправлять информацию вверх своему родительскому компоненту. Для отправки данных вверх требуются самоопределяемые события.

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

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

VueX - официальный плагин Vue. Он предлагает равный доступ ко всем компонентам, независимо от того, насколько глубоко они вложены.

VueX разработан с использованием шаблона singleton. Это общее место для хранения данных. Все компоненты считывают и записывают в один и тот же набор данных.

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

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

Данные, хранящиеся в VueX, называются состоянием. Мы можем создавать собственные геттеры на основе свойств состояния.

Чтобы изменить значения свойств состояния, нам нужны методы мутации. Только методы мутации могут изменять значения состояния, и все методы мутации должны быть синхронными. Для получения данных из API серверной части мы используем методы действий. Методы действий могут обрабатывать асинхронные операции.

И мутации, и действия - это методы VueX. VueX специально делит свой метод на две группы. Методы из группы мутации изменяют состояния, а методы из группы действий обрабатывают соединения с внутренними API. Такой дизайн гарантирует, что все изменения состояния являются синхронными и, следовательно, могут выполняться в предсказуемом порядке.

Для запуска методов мутации мы используем метод $ store.commit (). Что касается методов действий, мы используем метод $ store.dispatch ().

VueX разработан с использованием шаблона singleton. Есть только одна копия всего и все хранится в одном месте. По мере роста масштабов нашего проекта магазин VueX может сильно раздуться.

Чтобы помочь с этим, VueX позволяет нам разделить хранилище VueX на модули. Каждый модуль представляет собой вспомогательное хранилище со своими собственными состояниями, геттерами, мутациями и действиями. Модуль может даже иметь свои собственные дочерние модули.

Состояние, получатель, мутация, действие и модуль - пять основных концепций VueX.

Затем давайте создадим нашу первую программу VueX. Нам нужна версия VueX 4. Чтобы установить VueX, мы копируем адрес CDN.

В нашей программе Vue мы добавляем новый тег скрипта и устанавливаем его атрибут source, используя скопированный адрес CDN.

Теперь мы можем получить доступ к API VueX через Vuex.

Программа, которую мы используем, представляет собой очень простое приложение-счетчик. В корневом шаблоне мы отображаем свойство number. Когда мы нажимаем кнопку, мы запускаем метод increment, который увеличивает числовое значение на единицу. У нас также есть дочерний компонент. В настоящее время дочерний компонент отображает только заголовок.

Давайте добавим VueX в программу.

Сначала мы создаем константу. Мы называем это магазином. Магазин - это наиболее часто используемое название. Не выбирайте другие имена.

Мы устанавливаем значение хранилища с помощью метода createStore из API VueX. Мы передаем объект методу createStore. В этом объекте мы определили состояния, геттеры, мутации и действия. Мы называем этот объект объектом параметров VueX.

Затем мы добавляем экземпляр приложения с помощью метода use и передаем ему константу хранилища.

Теперь установка VueX завершена.

Давайте проверим экземпляр корневого компонента. Мы видим, что он получил новое свойство: магазин со знаками доллара.

То же свойство можно найти и в дочернем компоненте.

Если мы сравним эти два свойства хранилища, мы получим истину, потому что существует только одно хранилище VueX. Его разделяют все компоненты.

Объект, хранящийся в свойстве store знака доллара, на самом деле тот же объект, что и метод createStore.

Затем мы удаляем свойство number из параметра данных. Метод increment также больше не нужен.

В объекте createStore мы добавляем параметр состояния. Его синтаксис такой же, как и у параметра данных, который мы установили в объекте параметров компонента. Мы устанавливаем его значение с помощью функции и возвращаем в ней объект. Мы определяем свойства состояния в возвращаемом объекте.

Вы также можете напрямую назначить объект параметру состояния. Это то, что мы сделали с предыдущей версией VueX. Результаты такие же.

Причина, по которой мы выбираем более сложный синтаксис функции, заключается в том, чтобы гарантировать, что если мы повторно используем объект параметров при создании других модулей VueX, объект состояния не будет использоваться совместно. Функция создаст новый экземпляр объекта состояния. Мы покажем вам детали в уроках модуля.

Если вы не собираетесь повторно использовать объект параметров, вы можете использовать синтаксис объекта. Лично я буду постоянно использовать синтаксис функции.

Далее мы добавляем опцию мутации. Его ценность - это объект. Мы определяем метод мутации с именем increment.

Методы мутации автоматически получают объект состояния в качестве значения первого аргумента. Вот как они получают доступ к свойствам состояния. Мы добавляем единицу к номеру точки состояния.

Давайте проверим объект vm. $ Store. Находим свойство state и открываем его.

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

В шаблоне компонента мы можем получить доступ к свойствам состояния через $ store.state.

Чтобы запустить метод мутации, мы используем метод commit (). Метод commit также исходит из объекта $ store. Его первый аргумент - это имя метода мутации, который мы хотим запустить.

Теперь приложение счетчика готово. Он работает на VueX. Данные хранятся во VueX и изменяются методами мутации VueX.

Затем мы делаем копию тега H1 и button и вставляем их в шаблон дочернего компонента.

Дочерний компонент имеет доступ к тому же свойству состояния числа, что и родительский компонент. Если мы изменим числовое состояние в одном компоненте, другой компонент автоматически получит состояние после мутации.

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

Подробная информация о состоянии VueX

Теперь давайте внимательно посмотрим на свойства состояния VueX. Я предварительно определил три свойства состояния. Это марка, модель и год выпуска.

В шаблоне компонента мы отображаем свойства состояния, добавляя к их именам префикс $ store.state.

Такая длинная приставка действительно неудобна.

Мы можем отобразить свойства состояния в экземпляр компонента как вычисленные свойства. Откройте VueX API, вы найдете четыре метода, имена которых начинаются с map. Нам нужен метод mapState.

Мы устанавливаем вычисляемую опцию с помощью метода mapState. Мы передаем массив методу mapState. Мы устанавливаем элемент массива, используя имена свойств состояния. Не забудьте заключить элементы массива в кавычки. Вот уловка: в основном все из VueX нужно заключать в кавычки.

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

Мы запускаем метод mapState в таблице консоли. Посмотрим, что он вернет.

У нас есть объект. Свойства в этом возвращаемом объекте названы в честь элементов массива, переданных методу mapState. Значением свойства является функция mappedState. Эта функция предназначена для внутреннего использования, она помогает нам извлекать значения из состояния VueX.

Если мы установим значение вычисляемой опции с помощью метода mapState, мы не сможем установить наши собственные вычисляемые свойства.

Решение состоит в том, чтобы установить вычисляемый объект с использованием исходного синтаксиса. Внутри объекта мы добавляем к методу mapState оператор распространения. Свойства возвращенного объекта будут извлечены и вставлены в вычисляемый объект. Ниже метода mapState мы можем установить наши собственные вычисляемые свойства.

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

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

Установка псевдонимов - не основная причина, по которой мы используем синтаксис объекта. Мы используем синтаксис объекта для установки пользовательских геттеров.

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

Допустим, мы хотим создать свойство age, чтобы отразить возраст автомобиля.

Сначала мы создаем новый объект даты, чтобы получить текущий год. Затем мы вычитаем из него год точки состояния. Аргумент состояния дает нам доступ к свойствам состояния.

Подробности о VuX Getters

Параметр вычисленный является расширением параметра данных. Вычисляемые свойства - это просто методы получения и установки, основанные на свойствах данных.

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

В списке госимущества хранится информация о пяти автомобилях. Мы хотим перечислить все автомобили с ручным управлением.

В опции геттеров мы создаем новое свойство: manualCar. Его значение - функция получения.

Функции получения в VueX автоматически получают два аргумента: состояние и средства получения. Состояние - это первый аргумент, а получатель - второй.

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

Мы получаем доступ к массиву списка через список точек состояния. Мы добавляем к нему метод фильтрации, чтобы изолировать все автомобили с ручным управлением.

Используя метод mapGetters, мы можем сопоставить свойства получателя с вычисляемой опцией.

Мы можем выбирать из синтаксиса массива или синтаксиса объекта. Синтаксис объекта позволяет нам сопоставить геттер с другим именем. Но это все, что он может сделать, мы не можем определить другую функцию-получатель, как в методе mapState.

Таким образом, если вы хотите сохранить исходные имена получателей, передайте массив методу mapGetters. Если вы хотите сопоставить геттеры с новыми именами, используйте синтаксис объекта. Изменение имен - единственное, что вы можете сделать с синтаксисом объекта.

Теперь массив manualCar был вставлен в корневой уровень объекта экземпляра корневого компонента под тем же именем. В шаблоне компонента мы переключаем список на manualCar. Теперь в списке будут только автомобили с ручным управлением.

Теперь давайте попробуем второй аргумент: геттеры. Это дает нам доступ к объекту получателей, что означает, что мы можем создать получатель на основе другого получателя.

Например, мы хотим узнать общее количество машин с ручным управлением. Мы обращаемся к получателю manualCar, используя второй аргумент. Затем мы добавляем к нему свойство длины.

Подробнее о мутациях VueX

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

Имя метода мутации называется тип. Тело функции называется обработчиком. Функция-обработчик должна быть синхронной.

Все методы мутации автоматически получат объект состояния. Вот как они получают доступ к свойствам состояния. Они не полагаются на ЭТО.

Чтобы запустить метод мутации, мы используем метод commit. Мы передаем имя метода методу commit. Метод фиксации принимает второй аргумент. Он будет передан методу зафиксированной мутации в качестве значения второго аргумента. Если вам нужно передать несколько значений в метод зафиксированной мутации, поместите их в объект или массив.

Метод commit запускается внутри метода компонента. Мы можем передать ему свойства данных компонента.

Есть еще один способ установки метода commit. Передаем ему объект. Мы используем свойство type, чтобы указать, какой метод мутации мы хотим активировать. Не забудьте заключить название метода мутации в кавычки. Затем мы можем установить столько свойств, сколько захотим.

Весь объект, переданный методу commit, будет передан в метод зафиксированной мутации в качестве второго аргумента. Обычно мы называем второй аргумент payload. Нам нужно получить необходимое свойство из объекта полезной нагрузки.

Затем мы определяем новый метод мутации. Мы называем это декрементом. Он вычитает единицу из значения свойства состояния number.

На этот раз мы хотим сопоставить метод мутации Decment с экземпляром компонента. Метод mapMutations () аналогичен методу mapGetter (). Вы можете использовать синтаксис массива для сопоставления метода мутации с его собственным именем. Используя синтаксис объекта, вы можете выбрать другое имя.

Теперь метод мутации декремента сопоставлен с экземпляром корневого компонента с тем же именем. Мы вызываем его как обычный компонентный метод. Метод commit не нужен.

В наших реальных проектах лучше не отображать какие-либо мутации или методы действий. Просто активируйте их с помощью методов commit и dispatch.

V-модель и VueX

Здесь у нас есть тег ввода. Используя директиву v model, мы построили двусторонний путь между формой ввода и свойством данных сообщения.

Мы хотим переместить свойство message в состояние VueX, но мы требуем, чтобы входной тег оставался таким же, как и раньше. Другими словами, нам нужно включить директиву v module для работы со свойством состояния из VueX. Есть идеи, как это сделать?

В объект опций компонента мы добавляем вычисляемую опцию. Мы объявляем свойство message, используя синтаксис объекта. Мы устанавливаем для него геттер и сеттер.

В функции получения мы возвращаем это сообщение о состоянии точки в хранилище знака доллара.

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

Назовем новый метод мутации update. Мы присваиваем значение второго аргумента свойству состояния сообщения. Затем в функции установки мы «фиксируем» метод мутации update и передаем ему новое значение сообщения в качестве второго аргумента.

Теперь мы построили двусторонний путь к данным между свойством состояния сообщения и формой ввода. Ключевым моментом является установка записываемого вычисляемого свойства в качестве посредника.

Подробные сведения о действиях VueX

У нас есть полуфабрикат погодного приложения. Мы будем использовать VueX для получения описания погоды в выбранном городе.

Мы сохраняем название города в корневом компоненте и используем VueX для извлечения и хранения информации о погоде. Когда мы нажимаем кнопку, мы хотим загрузить информацию о погоде в текущем городе.

Получение данных из API серверной части является асинхронной операцией и, следовательно, должно выполняться с использованием методов действий.

Я уже установил axios. Заходим во VueX и добавляем опцию действий. Мы добавляем новый метод действия с именем query.

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

В методе триггера мы «отправляем» метод действия запроса. Мы передаем эту точку city методу dispatch в качестве значения второго аргумента. Теперь, когда мы нажимаем кнопку, название города будет передано методу действия query.

Первый аргумент context дает нам доступ ко всему хранилищу VueX. Мы можем получить доступ к свойствам состояния и получателя. Мы также можем совершать мутации и даже отправлять другие методы действий.

Затем давайте определим метод действия query. Сначала мы добавляем к нему префикс async.

Затем подготавливаем адрес API. Адрес API содержит две части внешней информации: название города и ключ подтверждения.

Название города происходит от аргумента функции. Мы можем получить к нему прямой доступ.

Ключ проверки хранится в состоянии VueX. Мы получаем к нему доступ через context. Мы префикс ключа с состоянием точки контекста.

Теперь адрес API установлен.

Мы добавляем оператор TRY CATCH.

В разделе TRY мы «ожидаем» метода axios get и передаем ему адрес API. Мы сохраняем возвращенный объект в переменной result. Затем мы записываем в консоль название города и полученное описание погоды.

В разделе CATCH мы записываем в консоль сообщение об ошибке.

Наша цель - присвоить полученное описание погоды свойству состояния description. Для этого нужен метод мутации.

Добавляем вариант мутации. Мы определяем метод мутации с именем update. Метод update присваивает значение своего второго аргумента свойству состояния description.

Вернемся в раздел TRY метода запроса.

Мы «фиксируем» метод мутации update и передаем ему полученное описание погоды.

Теперь программа готова.

Практика: создание приложения для погоды.

В этом разделе мы по-прежнему будем работать над приложением погоды. Но мы будем усложнять ситуацию, чтобы мы могли попробовать все, что узнали о VueX.

Город и описание являются свойствами состояния VueX, но нам не нужен длинный префикс в шаблоне компонента. Это требует от нас сопоставить их с экземпляром компонента.

Мы добавляем параметр вычисляемый и «распространяем» в нем метод mapState. Мы сопоставляем город и описание в экземпляре компонента.

Когда мы нажимаем кнопку города, мы запускаем метод change и передаем ему новое название города. Нам нужно передать новое название города в собственность города. Это требует от нас «зафиксировать» метод мутации.

Заходим в VueX и добавляем опцию мутации.

Мы определяем метод мутации с именем changeCity. Мы устанавливаем его второй аргумент с помощью state dot city. В методе change мы фиксируем метод мутации changeCity и передаем ему новое название города.

Теперь мы можем изменить название города, нажимая кнопки города.

Затем мы вернемся к VueX. Мы добавляем параметр действий и определяем метод асинхронного действия с именем query.

На последнем уроке мы установили два аргумента для метода запроса. Второй аргумент - это название города. Здесь мы используем другой подход. Мы сохраняем только первый аргумент. Мы не передаем название города в метод query.

Название города используется в адресе API. Мы можем сгенерировать адрес API с помощью геттера. В опции геттеров мы создаем геттер с именем API. В нем возвращаем адрес API. И город, и ключевые значения происходят из состояния VueX. Мы ставим перед ними префикс состояния.

Теперь каждый раз, когда мы меняем название города, метод получения API будет возвращать новый адрес API.

В методе действия query мы добавляем оператор TRY CATCH. В разделе TRY мы ждем метода axios get. Мы передаем API-интерфейс получения точек контекста методу get. Когда мы меняем название города, адрес API обновляется автоматически. Затем мы сохраняем возвращенный объект в переменной с именем result. Консоль ведем журнал с названием города и описанием погоды.

Нам нужен метод мутации для обновления свойства состояния описания. Мы называем это updateWeather. В методе действия запроса после получения описания погоды мы «фиксируем» метод мутации updateWeather и передаем ему полученное описание погоды.

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

Теперь наша работа на стороне VueX завершена.

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

Затем мы добавляем созданный обработчик и отправляем в него действие query. Это для загрузки исходных данных.

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

Модули VueX

VueX хранит только один набор данных. Но по мере того, как наши проекты становятся все более завершенными, одного набора данных может оказаться недостаточно. Вот почему представлены модули VueX.

Помимо корневого хранилища, мы можем создать для него несколько дочерних хранилищ. Каждый детский магазин независим и не мешает другим магазинам.

В объекте, переданном методу createStore, мы определяем корневые модули. Добавляем опцию «модули» и назначаем ей объект. В этом объекте мы объявляем дочерние модули VueX.

Создаем два модуля: модуль A и модуль B.

В модуле A мы добавляем параметр состояния и объявляем свойство заголовка. В модуле B делаем то же самое. Эти два состояния заголовка независимы.

Далее мы регистрируем эти два модуля в опции «модули». Имена свойств, которые мы установили в опции модулей, будут использоваться как имена модулей.

Давайте проверим переменную store.

Открываем государственный объект. Мы видим, что объект состояния получил два дочерних объекта. Они названы по имени модуля. Свойства состояния из двух дочерних модулей хранятся в этих двух объектах.

Свойства состояния, определенные в объекте параметров метода createStore, являются свойствами корневого состояния. Свойства корневого состояния хранятся на корневом уровне объекта состояния. Вот почему у нас есть два свойства состояния под одним и тем же именем, но они не конфликтуют друг с другом.

Теперь у нас есть три свойства состояния под названием title. Давайте сопоставим их с объектом экземпляра компонента.

Добавляем вычисляемый вариант. Мы устанавливаем метод mapState, используя синтаксис объекта, чтобы мы могли установить псевдонимы для трех свойств состояния заголовка.

Для свойств корневого состояния мы можем напрямую обращаться к ним по имени. Для свойств состояния из дочерних модулей нам понадобится синтаксис функции. Мы возвращаем состояние точка имя модуля имя свойства точки.

Теперь три свойства заголовка сопоставлены с экземпляром корневого компонента. Мы получаем к ним доступ через их псевдонимы.

Далее попробуем геттеры. В модуле A мы добавляем опцию получения и создаем средство получения capTitle. Мы возвращаем заглавное значение заголовка.

Функция получения имеет три аргумента. Первый - это объект состояния текущего модуля. Второй - объект-получатель текущего модуля. Третий указывает на объект корневого состояния. Чтобы получить доступ к свойствам состояния из текущего модуля, мы используем первый аргумент.

Затем мы делаем копию опции геттеров и вставляем ее в модуль B. Теперь у нас есть два получателя capTitle. Вызовут ли они какие-либо конфликты имен?

Мы получили сообщение об ошибке. Он говорит о дублировании ключа-получателя.

Если мы отключим один получатель capTitle, сообщение об ошибке исчезнет.

Геттеры из всех модулей будут напрямую объединены в корневой уровень объекта геттеров. В отличие от объекта состояния, здесь не будет дочерних объектов.

Пространство имен

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

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

Свойства корневого состояния будут храниться на корневом уровне объекта состояния. Те из дочерних модулей, будут храниться в дочерних объектах, названных по именам их модулей. Эта функция доступна только для состояния свойств.

Геттеры из всех модулей будут объединены в один объект. Следовательно, идентичные имена получателей вызовут конфликты имен.

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

Мы добавляем параметр namespaced в модуль A и устанавливаем для него значение true. Не пропустите последнюю букву D.

Модуль B еще не включил пространство имен, поэтому его получатель не имеет префикса.

Рекомендуется включить пространство имен для всех модулей, кроме корневого модуля. Включение пространства имен для корневого модуля бессмысленно, поскольку корневой модуль не имеет имени, в результате корневые методы получения не получат никакого префикса.

Затем мы сопоставляем эти три метода получения capTitle с экземпляром компонента.

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

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

Для доступа к корневым геттерам мы напрямую используем их имена.

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

Иногда компоненту могут потребоваться геттеры только из одного модуля. В этом случае мы можем указать пространство имен целевого модуля в методе mapGetters.

Мы передаем имя модуля методу mapGetters в качестве значения его первого аргумента. Теперь этот метод mapGetters работает только с модулем A. Нам больше не нужно ставить перед именами получателей префикс имени модуля.

Все методы карты поддерживают пространство имен. Например, мы добавляем метод mapState и устанавливаем для его первого аргумента значение A. Теперь метод mapState отображает только свойства состояния из модуля A.

Объект состояния, переданный методу aTitle, содержит только свойства из объекта состояния модуля A.

Те же правила распространяются и на мутации и действия.

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

В объекте мы добавляем свойство root и устанавливаем его значение в true.

Затем мы добавляем свойство обработчика для определения тела функции. Метод обработчика такой же, как и у обычного метода действия. У него два аргумента: контекст и полезная нагрузка. Значение полезной нагрузки зависит от того, как отправляется метод тестового действия.

Метод тестового действия является глобальным, но он все еще определен в модуле A. Свойство состояния в своем объекте контекста по-прежнему указывает на объект состояния модуля A, а не на корневой объект состояния.

Чтобы получить доступ к корневым состояниям или состояниям из других модулей, используйте свойство rootState. То же самое и с геттерами. Есть свойство getters и свойство rootGetters.

Затем мы делаем копию тестового действия и вставляем ее в корневой модуль.

Теперь у нас есть два метода тестовых действий, но оба они глобальные. Давайте посмотрим, как VueX справится с этой ситуацией.

Давайте обновим страницу и проверим объект магазина.

В действиях подчеркивания есть только одно свойство test, но его значение представляет собой массив. Здесь хранятся оба метода тестового воздействия.

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

Динамические модули VueX

В этом разделе мы поговорим о динамических модулях.

Регистрируем динамические модули с помощью метода registerModule. Метод registerModule имеет два аргумента. Первый - это имя модуля, а второй - объект параметров для определения модуля. Объект параметров - это просто обычный объект. Мы можем использовать это многократно.

Используя метод hasModule, мы можем проверить, зарегистрировано ли имя модуля или нет.

Используя метод unregisterModule, мы можем удалить модуль.

Затем мы делаем копию метода registerModule. Назовем новый модуль A2. A1 и A2 созданы с использованием одного и того же объекта параметров.

Помните, мы упоминали, что лучше всего устанавливать параметр состояния, используя синтаксис функции? Теперь вы поймете, почему.

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

Давайте сбросим его параметр состояния, используя синтаксис объекта. Мы удаляем функцию и напрямую назначаем объект параметру состояния.

Давайте перезагрузим страницу и сбросим состояние заголовка из модуля A1.

Тогда давайте проверим состояние объекта.

Теперь мы видим проблему. Также изменилось название модуля A2.

Модуль A 1 и A2 совместно используют один и тот же объект состояния. Изменение свойств состояния модуля A1 также повлияет на модуль A2.

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

Для объектов параметров, которые никогда не будут использоваться повторно, можно использовать синтаксис объекта. Но лично я всегда буду придерживаться синтаксиса функции.

Метод registerModule принимает объект конфигурации в качестве третьего аргумента. Мы можем установить в нем свойство preserverState.

Установка для свойства preserveState значения true предотвращает добавление свойств состояния модуля в хранилище VueX.

VueX предполагает, что текущее хранилище уже содержит состояние для этого модуля, и вы не хотите его перезаписывать. Другими словами, для модулей, свойства состояния которых не нужны, вы можете установить для preserveState значение true, чтобы отказаться от них.

Это также означает, что мутации и геттеры из этого модуля больше не работают.

Если мы «зафиксируем» метод мутации changeTitle из модуля A1, мы получим сообщение об ошибке, потому что свойство состояния заголовка не было добавлено в хранилище VueX.

Плагины VueX

В этом разделе мы изучим плагины VueX.

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

В корневом модуле мы добавляем опцию плагинов и назначаем ей массив. В этом массиве мы регистрируем функции плагина. Назовем его P1.

Затем мы определяем функцию с именем P1. Функции плагина получат объект магазина.

Функции плагина будут запускаться автоматически при первой загрузке программы. Отправка действий или фиксация мутаций больше не вызовут функцию плагина.

Чтобы отслеживать методы мутации или действия, нам нужны два метода подписки. Метод subscribe отслеживает методы мутации. Для методов действия используйте метод subscribeAction.

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

В плагине P1 мы добавляем метод subscribe для отслеживания мутаций. Мы передаем обратный вызов методу подписки. У этого обратного вызова есть два аргумента: мутация и состояние.

Первый аргумент обратного вызова - это объект с двумя свойствами.

Используя свойство type, мы можем определить, какой метод мутации запускается. Свойство payload хранит значение аргумента, переданное методу мутации.

Второй аргумент - это объект состояния хранилища VueX. Он отражает последнее состояние, то есть свойства в нем уже «видоизменены».

Вы можете добавить столько методов subscribe, сколько захотите. Они будут помещены в очередь и выполнены в том же порядке, в котором они были добавлены.

Мы можем выбрать метод подписки и переместить его в начало очереди, чтобы он выполнялся первым.

За обратным вызовом выбранного метода подписки мы добавляем объект конфигурации. Мы устанавливаем для prepend значение true. Теперь второй метод подписки будет добавлен в первую позицию очереди. В результате он будет выполнен первым.

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

Я установил нижнюю черту, которая представляет собой библиотеку функций JS. У него есть метод cloneDeep. Создает глубокую копию объекта. Глубокая копия означает копирование всех вложенных объектов.

Вне метода подписки мы делаем глубокий клон объекта состояния и сохраняем копию в переменной с именем pre. Объект состояния поступает из объекта хранилища, переданного функции плагина. Это состояние до мутации.

Внутри обратного вызова метода подписки мы делаем второй глубокий клон объекта состояния. Мы сохраняем скопированный объект в переменной с именем post.

На этот раз объект состояния исходит из второго аргумента обратного вызова. Это постмутационное состояние.

Теперь pre сохраняет старое состояние, а post - новое состояние.

Выводим их для сравнения.

В конце концов, мы назначаем пост pre. Обратите внимание, присвоение значения должно быть размещено в самом конце, после того, как мы выведем pre и post.

Попробуем программу.

Теперь мы можем сравнить состояния до и после мутации. Техника глубокого клонирования предназначена только для целей разработки. Не используйте его в производственной среде.

Метод подписки возвращает метод отказа от подписки. При его вызове метод подписки будет отменен.

Для отслеживания методов действий мы используем метод subscribeAction. Его синтаксис такой же, как у метода подписки. Переданный ему обратный вызов получает два аргумента: действие и состояние.

Аргумент действия по-прежнему является объектом с двумя свойствами: типом и полезной нагрузкой.

Тип сообщает нам имя отправленного метода действия. Payload сообщает нам значение аргумента, переданное методу отправленного действия.

Методы действия не изменяют свойства состояния. Следовательно, аргумент состояния хранит состояния до мутации.

Вы также можете установить метод subscribeAction, используя синтаксис объекта. Вместо того, чтобы передавать ему обратный вызов, мы передаем ему объект. Объект позволяет нам установить два метода: до и после.

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

Метод before запускается перед отправкой метода действия. Естественно, он находится в предмутационном состоянии.

Метод after запускается после отправки метода действия. Метод мутации является синхронным и фиксируется внутри метода действия. Следовательно, метод after также запускается после метода мутации. В результате он находится в постмутационном состоянии.

Если подписанный метод действия запрашивает серверный API, метод before будет запущен прямо перед запуском запроса. Метод after будет запущен после завершения запроса. Мы можем использовать эти два метода для включения и выключения уведомления о загрузке.

VueX Composition API

В этом разделе мы расскажем, как использовать VueX в функции setUp.

Проблема в том, как получить доступ к хранилищу VueX в функции setUp. Экземпляр компонента еще не создан. Так что this. $ Store здесь не работает.

Мы объявляем переменную с именем store. Мы устанавливаем его значение с помощью метода createStore. Теперь мы можем получить доступ к хранилищу VueX в функции setUp. Метод useStore найдет установленное хранилище VueX и вернет его.

Допустим, мы хотим добавить состояния num и title в экземпляр компонента.

В функции setUp мы возвращаем объект. В возвращаемом объекте мы добавляем свойство number и устанавливаем его значение с помощью метода computed. Мы устанавливаем функцию получения и возвращаем в ней номер точки состояния точки.

Обратите внимание, само свойство состояния number не добавляется в экземпляр компонента. Свойство number в возвращаемом объекте фактически является получателем для состояния числа.

Когда мы изменяем состояние number, возвращаемое свойство number изменится соответствующим образом. Вот почему мы предпочитаем вычисляемый метод методу ref.

Что касается свойства title, мы можем установить его значение с помощью метода ref, потому что мы не собираемся изменять состояние title. Если реактивность не требуется, можно даже пропустить метод ref.

Если задуматься, свойства number и title в возвращаемом объекте - это просто оболочки для свойств состояния VueX.

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

Мы определяем метод оболочки для метода мутации numberUp. Мы называем его shellNumUp.

Чтобы добавить метод действия к экземпляру компонента, мы по-прежнему создаем метод оболочки. Метод оболочки отправляет целевое действие.

Таким образом, функция setUp может легко добавлять состояния и методы VueX в экземпляр компонента. Нам просто нужно поместить их в возвращаемый объект. Метод карты больше не нужен.

Для состояний и геттеров мы возвращаем их в вычисляемом методе.

Для мутаций и действий мы создаем для них метод оболочки. Единственная задача метода оболочки - зафиксировать или отправить целевой метод.

[Продолжение следует…]