Как стать автором
Обновить
1055.07
OTUS
Цифровые навыки от ведущих экспертов

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

Время на прочтение4 мин
Количество просмотров17K
Автор оригинала: Gábor Soós

Реактивность в 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;
— создадим механизм стилизации через подключаемые темы.


РЕГИСТРАЦИЯ

Теги:
Хабы:
Всего голосов 11: ↑10 и ↓1+9
Комментарии5

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS