Harlem — простая альтернатива Vuex для Vue 3.

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

В этой статье предполагается, что у вас есть базовые знания о Vue и Vuex.

Начиная с любого внешнего интерфейса или библиотеки, управление состоянием всегда является темой, которую вы изучаете в Интернете, для Vue первым рекомендуемым вариантом, который вы найдете, является Vuex — библиотека, основанная на шаблоне потока для управления состоянием. Однако Harlem является альтернативой Vuex и претендует на звание беспристрастной, легковесной и расширяемой библиотеки управления состоянием для Vue 3. Давайте посмотрим, как это сделать.

Начиная

Довольно легко начать работать с Гарлемом. Согласно документации, вам нужно всего лишь установить harlem/core :

yarn add @harlem/core

Затем используйте магазин Harlem в своем файле входа.

// main.js
...
import Harlem from '@harlem/core';
...
createApp(App).use(Harlem).mount('#app')

Мы можем прямо сейчас смоделировать тележку в нашем магазине. Используя приложение vue 3 по умолчанию (сгенерированное с помощью vue-cli), мы можем добавить папку stores и создать модуль корзины в этой папке. Это будет выглядеть примерно так:

Состояние

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

Функция createStore используется для создания новых экземпляров (подумайте об экземпляре как о модуле) хранилищ, которые имеют свои собственные геттеры, мутации и т. д.

Функция createStore принимает 3 аргумента, первый — имя экземпляра магазина (имя модуля), в нашем случае корзина, второй аргумент — объект базового состояния, третий необязательный аргумент — это параметры магазина. Эта функция возвращает экземпляр объекта хранилища, который, в свою очередь, раскрывает его состояние, мутацию, геттер.

Параметры магазина

Опция store передается в качестве третьего аргумента функции createStore. С помощью этого аргумента мы можем указать некоторые интересные параметры, такие как allowOverwrite, providers, или extensions. Обновим функцию createStore и изменим одного провайдера.

Одним из провайдеров, разрешенных Гарлемом, является payload — с помощью этой функции мы можем перехватывать и модифицировать каждую полезную нагрузку до того, как она будет отправлена ​​на мутацию. Вы можете найти других возможных поставщиков здесь:



Я бы не рекомендовал делать что-то подобное для каждой полезной нагрузки, отправляемой в мутацию (однако могут быть варианты использования). В идеале вы хотели бы изменить полезную нагрузку только для определенных видов мутаций, и да, Harlem также позволяет вам легко сделать это с помощью подписчика onBeforeMutation:

Мутация

Как определить мутацию?

Функция createStore возвращает экземпляр хранилища, который предоставляет некоторые полезные функции, в том числе функцию mutation. Функция mutation используется для определения метода изменения конкретной части состояния.

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

И даже больше:

Добытчики

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

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

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

В приведенном выше примере мы импортировали объект state, addToCart и populateStoreмутацию, cartItems и availableItems геттер. Важно отметить, что состояние всегда readonly, поэтому мы можем получить доступ к значению cartName в нашем шаблоне, выполнив state.cartName, но мы не можем изменить значение, назначив state.cartName новое значение:

state.cartName = 'New Cart Name'
// Set operation on key "cartName" failed: target is readonly. Proxy // {cartName: 'Black Friday Cart', items: Array(0)}

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

В разделе template нашего компонента мы можем просто напрямую использовать значение состояния и геттеры, мы также можем использовать их в методах и вычисляемых свойствах:

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

Обратите внимание, что мы прикрепили метод add(item) к прослушивателю нажатия кнопки «Добавить в корзину». В этой функции мы можем вызвать мутацию addToCart, которую мы импортировали из нашего хранилища, и передать элемент в качестве полезной нагрузки:

Двусторонняя привязка

Еще одна интересная вещь, которую мы можем сделать с Harlem, — это привязать любое свойство нашего магазина к нашему шаблону с помощью v-model. Допустим, пользователи могут изменить имя корзины, мы можем добавить элемент ввода и связать его с переменной, которая получает и устанавливает значение state.cartName:

Далее вам нужно только определить и экспортировать мутацию setCartName в файл cart.js:

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

Собираем все вместе

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

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

Это все здорово, но как нам осмотреть наш магазин в Гарлеме и убедиться, что он ведет себя именно так, как мы ожидаем? — Плагин Harlem Devtool + инструмент разработки Vue.

Инструмент разработчика

Vuex поддерживается по умолчанию в Vue dev tool, это не относится к Гарлему (на момент написания статьи). Однако мы можем включить поддержку Harlem, установив в наш проект Harlem Devtool Plugin.

npm i @harlem/plugin-devtools
or using yarn
yarn add @harlem/plugin-devtools

Затем в вашем файле записи main.js вы можете импортировать и включить в него список плагинов для Harlem:

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

Давайте еще раз взглянем на нашу торговую площадку с открытым инструментом разработки.

Действия

В Harlem действия не включены по умолчанию, в отличие от Vuex, это в основном потому, что Harlem проповедует простоту и легкость, и, учитывая самую простую реализацию магазина, вам, скорее всего, не понадобятся действия. . Как правило, действия — это асинхронные методы, которые объединяют сетевые запросы с одной (или несколькими) мутациями состояния.

Чтобы включить действия в Гарлеме, мы установили библиотеку @harlem/extension-action.

npm i @harlem/extension-action
or using yarn
yarn add @harlem/extension-action

Затем зарегистрируйте это расширение в модуле, в который вы хотите включить действия (в нашем случае это модуль корзины). Мы можем сделать это внутри StoreOptions функции createStore:

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

Давайте внесем некоторые изменения. Используя функцию action, теперь мы можем определить новое действие — fetchStoreData, для извлечения данных из FakeStore API и вызова мутации populateStore.

Теперь мы можем обновить наш хук onMounted, чтобы он вызывал действие fetchStoreData.

Хранить постоянство

Иногда вы хотите заполнить свой магазин сохраненными данными из хранилища браузера. С Vuex мы можем сделать это, используя такие библиотеки, как vuex-persistedstate, мы можем добиться той же функциональности в Гарлеме с официальным расширением хранилища, которое добавляет возможность синхронизации состояния хранилища с/из localStorage или sessionStorage.

Как и любое другое расширение Harlem, оно устанавливается по требованию.

yarn add @harlem/extension-storage

Затем импортируйте и добавьте в список плагинов:

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

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

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

Вот ссылка на исходный код для этого примера проекта:



И Вот ссылка на демонстрационное приложение, развернутое на Surge.

Привет ☕️