Почему вам не нужно использовать Vuex в Vue3

Vue.js

исходный адрес:medium.com/better-pro Страна…

Переводчик:Gavin, несанкционированное воспроизведение запрещено.

предисловие

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

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

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

  • Несколько компонентов используют одни и те же данные
  • Несколько корневых модулей должны иметь доступ к данным отдельно
  • Компоненты с глубокой вложенностью должны взаимодействовать с другими компонентами.

Если ничего из вышеперечисленного нет, решение простое: оно вам не нужно.

Что делать, если описанная выше ситуация имеет место? Самый простой ответ — использовать Vuex, проверенное в боевых условиях решение, которое хорошо работает.

Если вы не хотите добавлять еще одну зависимость или не хотите делать слишком много настроек? Итак, теперь вы можете решить эти проблемы с помощью новых встроенных методов Vue3 вместе с Composition API.

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

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

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

Отзывчивый

Vue3 предоставляет множество функций своей адаптивной системы, вы можете использоватьreactiveфункция создает реактивную переменную (вы также можете использоватьrefфункция)

import { reactive } from 'vue';

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

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

<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>

Доступность

Приведенный выше пример отлично подходит для одного компонента, но не для общего состояния нескольких компонентов. Чтобы преодолеть это, вы можете использовать Vue3provideи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Функция оборачивает состояние, чтобы оно стало受保护Состояние необходимо обрабатывать с помощью отдельной функции, когда состояние необходимо изменить.

import { reactive, readonly } from 'vue';

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

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

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

пройти через受保护的状态Избегая ненужных модификаций, новое решение относительно ближе к Vuex.

Резюме

С помощью Vue3响应式系统и依赖注入Механизм, мы изменили локальное управление состоянием на глобальное управление состоянием, это решение может заменить Vuex в небольших приложениях.

У нас есть объект состояния, доступный только для чтения, и мыtemplatesреагировать на изменения в . Это состояние можно изменить только с помощью определенного метода, аналогичного Vuex.actions/mutations,ты можешь использоватьcomputedФункции определяют другие геттеры.