Новости программирования

Практическое руководство по Гарлему

Краткое описание по статье Практическое руководство по Гарлему

Название: Практическое руководство по Гарлему . Краткое описание: [ad_1] ⭐ В этой статье предполагается, что у вас есть . Дата публикации: 02.02.2022 . Автор: Алишер Валеев .

Для чего создан сайт Novosti-Nedeli.ru

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

Сколько лет сайту?

Возраст составляет 3 года

[ad_1]

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

1*tHA4MrKpvwwEB5bNv8V1Wg.png

Состояние

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

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

const BASE_STATE = {
  cartName: 'Black Friday Cart',
  shop: [],
  items: []
};

export const { state } = createStore('cart', BASE_STATE, {})

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

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

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

export const { state } = createStore('cart', BASE_STATE, {
  provider: {
    payload: value => ({ createdAt: new Date(), ...value })
  }
});

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

Типы Гарлема

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

export const {
  onBeforeMutation
} = createStore('cart', BASE_STATE, {})

onBeforeMutation('addToCart', ({ mutation, payload, result }) => {
  // do something with payload
})

Мутация

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

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

export const {
  ...
  mutation
} = createStore('cart', BASE_STATE, { });

export const addToCart = mutation('addToCart', (state, payload) => {

  state.items.push(payload)

  state.shop = state.shop.map(item => {
    if (item.id === payload.id) {
      item.isAvailable = false
    }
    return item
  })
})

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

export const removeFromCart = mutation('removeFromCart', (state, payload) => {
  state.items = state.items.filter(x => x !== payload)
  state.shop = state.shop.map(item => {
    if (item.id === payload.id) {
      item.isAvailable = true
    }
    return item
  })
})

export const clearCart = mutation('clearCart', state => {
  state.items = []
  state.shop = state.shop.map(item => ({ ...item, isAvailable: true }))
})

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

export const populateStore = mutation('populateCart', (state, payload) => {
  state.shop = payload;
})

Добытчики

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

export const {
  ...
  getter
} = createStore('cart', BASE_STATE, { ... });

export const cartItems = getter('cartItems', state => {
  return state.items
});

export const availableItems = getter('availableItems', state => {
  return state.shop.filter(item => item.isAvailable);
})

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

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

<script setup>
  ...
  import {
      state,
      addToCart,
      cartItems,
      clearCart,
      setCartName,
      availableItems,
      fetchStoreData,
  } from './stores/cart';
  ...
</script>

В приведенном выше примере мы импортировали state объект, addToCart и populateStore мутация, cartItems и availableItems добытчик. Важно отметить, что состояние всегда доступно только для чтения, поэтому мы можем получить доступ к значению 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)}

Так что во что бы то ни стало всегда сохраняйте шаблон потока при работе с хранилищами — изменяйте хранилище только внутри функции-мутатора.
1_nvizph0doemlaxmt-gg5kg.png

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

<template>
  ...
    <h3>{{ state.cartName }} ({{ cartItems.length }})</h3>
  ...
</template>

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

<div class="store">
  <div class="store__product"
    v-for="(item, index) in availableItems"
    :key="index"
  >
    <div class="store__product_image">
      <img width="200" :src="item.image" :alt="item.title">
    </div>
    <div class="store__product_content">
      <div class="store__product_description">
        {{ item.title }}
      </div>
      <div class="store__product_price">$ {{ item.price }}</div>
      <button class="atc" @click="add(item)">Add To Cart</button>
    </div>
  </div>
</div>

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

<script setup>
  ...
  const add = (item) => {
    addToCart(item)
  }
</script>

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

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

<template>
  ...
  <input type="text" v-model="cartName">
  ...
</template>

<script setup>
  import { computed } from 'vue';

  import {
    ...
    state,
    setCartName
  } from './stores/cart';

  const cartName = computed({
    get: () => state.cartName,
    set: value => setCartName(value)
  })
</script>

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

export const setCartName = mutation('setCartName', (state, payload) => {
  state.cartName = payload
})

Теперь у вас должно быть правильно привязано свойство магазина к полю ввода.
1*qvgjC83oEdXHLebIVog9DQ.gif

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

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

import { onMounted } from 'vue';
import {
  ...
  populateStore
} from './stores/cart';

onMounted(() => {
  fetch('https://fakestoreapi.com/products')
    .then(res => res.json())
    .then(json => populateStore(json.map(
      ({ id, title, price, description, image }) => ({
        id,
        title,
        price,
        description,
        image,
        isAvailable: true
      })
    )))
})

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

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

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

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

npm i @harlem/plugin-devtools

or using yarn

yarn add @harlem/plugin-devtools

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

import devtoolsPlugin from '@harlem/plugin-devtools';

createApp(App)
  .use(Harlem, {
    plugins: [
      devtoolsPlugin({
        label: 'Harlem Store'
      })
    ]
  })
  .mount('#app')

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

1_iuxxqfdqowwjshvvqqwh6q.png

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

Действия

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

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

npm i @harlem/extension-action

or using yarn

yarn add @harlem/extension-action

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

import { createStore } from '@harlem/core';
import actionExtension from '@harlem/extension-action';

export const {
  ...
  action
} = createStore('cart', BASE_STATE, {
  extensions: [ actionExtension() ]
});

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

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

export const { action } = createStore(...)

export const fetchStoreData = action('fetchStoreData', async () => {
  const data = await fetch('https://fakestoreapi.com/products').then(res => res.json())
  const items = data.map(({ id, title, price, description, image }) => ({
    id,
    title,
    price,
    description,
    image,
    isAvailable: true
  }))
  populateStore(items)
})

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

import {
  ...
  fetchStoreData
} from './stores/cart';

onMounted(() => {
  fetchStoreData()
})

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

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

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

yarn add @harlem/extension-storage

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

import storageExtension from '@harlem/extension-storage';
...

export const {
  ...
  startStorageSync,
  stopStorageSync,
  clearStorage
  ...
} = createStore('cart', BASE_STATE, {
  extensions: [
    ...
    storageExtension({
      type: 'local',
      prefix: 'marketplace',
      sync: true,
      exclude: [],
      serialiser: state => JSON.stringify(state),
      parser: value => JSON.parse(value)
    })
  ]
});

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

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

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

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

https://github.com/MartinsOnuoha/Чак-Норрис

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

Привет ☕️

[ad_2]
Source: codementor.io/community/new

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован.

Кнопка «Наверх»