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

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

Вам нужно общее состояние?

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

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

Если ни один из вышеперечисленных случаев не соответствует действительности, ответ прост, нужен он вам или нет. Вам это не нужно.

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

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

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

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

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

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

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.

Похожие записи

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *