С Vue 3 вам может и не понадобиться Vuex

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

Реактивность в Vue 3 представляет новые способы структурирования приложения

Vuex — это потрясающая библиотека управления состояниями. Она проста и хорошо интегрируется с Vue. Зачем кому-то уходить от Vuex? Причина может быть в том, что предстоящий релиз Vue 3 раскроет заложенную в ее основе систему реактивности и предложит новые способы структурирования приложения. Новая система реактивности настолько мощная, что это можно использовать для централизованного управления состояниями.

. . .

Нужно ли вам общее состояние?

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

  • Несколько компонентов, использующих одни и те же данные.

  • Несколько корневых элементов (roots) имеющих доступ к данным.

  • Глубокая вложенность компонентов.

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

Как быть, если у вас есть один из этих случаев? Прямым ответом будет использование Vuex. Это проверенное решение, которое отлично справляется со своей задачей.

Что, если вы не хотите добавлять еще одну зависимость или считаете настройку слишком сложной? Вместе с API Composition новая версия Vue 3 может решить эти проблемы с помощью своих встроенных методов.

. . .

Новое решение

Общее состояние должно соответствовать двум критериям:

  • Реактивность: Когда состояние изменяется, компоненты, использующие его, также должны обновляться.

  • Доступность: К состоянию можно получить доступ в любом из компонентов.

. . .

Реактивность

Vue 3 раскрывает свою систему реактивности через множество функций. Вы можете создать реактивную переменную с помощью функции reactive (альтернативой может быть функция ref):

import { reactive } from 'vue';

export const state = reactive({ counter: 0 });

Объект, возвращаемый из функции reactive, является объектом Proxy, который может отслеживать изменения своих свойств. При использовании в шаблоне компонент рендерится заново при каждом изменении значения реактивной функции.

<template>
  <div>{{ state.counter }}</div>
  <button type="button" @click="state.counter++">Increment</button>
</template>

<script>
  import { reactive } from 'vue';

  export default {
    setup() {
      const state = reactive({ counter: 0 });
      return { state };
    }
  };
</script>

Доступность

Приведенный выше пример прекрасно подходит для одного компонента, но при этом другие компоненты не могут получить доступ к состоянию. Чтобы решить эту проблему, вы можете сделать любое значение доступным внутри приложения Vue 3 с помощью методов provide и inject.

import { reactive, provide, inject } from 'vue';

export const stateSymbol = Symbol('state');
export const createState = () => reactive({ counter: 0 });

export const useState = () => inject(stateSymbol);
export const provideState = () => provide(
  stateSymbol, 
  createState()
);

Когда вы передаете Symbol в качестве ключа и значение в метод provide, оно будет доступно для любого дочернего компонента через метод inject. Ключ использует одно и то же имя Symbol при предоставлении и получении значения.

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

import { createApp, reactive } from 'vue';
import App from './App.vue';
import { stateSymbol, createState } from './store';

const app = createApp(App);
app.provide(stateSymbol, createState());
app.mount('#app');
<script>
  import { useState } from './state';

  export default {
    setup() {
      return { state: useState() };
    }
  };
</script>

Обеспечение надежности

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

Можно сделать состояние защищенным, обернув его функцией readonly. Она покрывает переданную переменную в объекте Proxy, который предотвращает любые изменения (выдает предупреждение, когда вы пытаетесь это сделать). Мутации могут обрабатываться отдельными функциями, имеющими доступ к хранилищу с возможностью записи.

import { reactive, readonly } from 'vue';

export const createStore = () => {
  const state = reactive({ counter: 0 });
  const increment = () => state.counter++;

  return { increment, state: readonly(state) };
}

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

По защите состояния от нежелательных изменений новое решение сравнимо с Vuex.

Резюме

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

У нас есть объект состояния, который доступен только для чтения и реагирует на изменения в шаблонах. Состояние может быть изменено только с помощью специальных методов, таких как команды/мутации в Vuex. Вы можете определить дополнительные геттеры с помощью функции computed.

Vuex имеет больше возможностей, таких как обработка модулей, но порой нам это не нужно.

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

Все коды на изображениях для копирования доступны здесь.


Материал подготовлен в рамках курса «Vue.js разработчик».

Также приглашаем всех желающих на открытый урок «DatePicker». Разберем DatePicker, а именно:
— создадим библиотеку компонентов, чтобы получать DatePicker-ы c нужными параметрами;
— реализуем передачу данных через Provide/Inject;
— продемонстрируем композицию объектов через extend;
— создадим механизм стилизации через подключаемые темы.


РЕГИСТРАЦИЯ

Источник: https://habr.com/ru/company/otus/blog/570138/


Интересные статьи

Интересные статьи

Когда вы в последний раз переписывались по SMS? Если не считать смс-рассылок и уведомлений от вашего сотового оператора, то вы, скорей всего, давно не пользовались службой коротких сооб...
Маркетплейс – это сервис от 1С-Битрикс, который позволяет разработчикам делиться своими решениями с широкой аудиторией, состоящей из клиентов и других разработчиков.
Ранее в одном из наших КП добавление задач обрабатывалось бизнес-процессами, сейчас задач стало столько, что бизнес-процессы стали неуместны, и понадобился инструмент для массовой заливки задач на КП.
Проверьте себя: а на какое количество вопросов ЧГК сможете ответить вы? Для затравки: в 1979 году, еще до выхода своей компании на биржу, Стив Джобс провел тесты, не имеющие отношения непосре...
Автокэширование в 1с-Битрикс — хорошо развитая и довольно сложная система, позволяющая в разы уменьшить число обращений к базе данных и ускорить выполнение страниц.