Новый Composition API позволяет избавиться от Vuex хранилища. Рассмотрим простейший пример, как этого добиться. И рассмотрим за и против.

Пример


Пример счетчика на Vuex возьмем из документации the-simplest-store, и реализуем его с помощью composition API.

Модуль счетчика modules/counter.ts:

import { ref } from 'vue'

const counter = ref(0)

export default function useCounter () {
  const increment = () => {
    counter.value++
  }
  return { counter, increment }
}

Обратите внимание, что переменная counter находится вне функции useCounter(). Таким образом при вызове функции useCounter в разных компонентах counter будет ссылаться на один и тот же экземпляр. А это то, что нам и нужно.

Использовать наш счетчик в разных компонентах просто:

<template>
    <div>
      {{ counter }}
    </div>
   <button @click="increment">+</button>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import useCounter from '@/modules/useCounter'

export default defineComponent({
  name: 'App',
  setup () {
    const { counter, increment } = useCounter()
    return { counter, increment }
  }
})
</script>

Чтобы воспользоваться глобальным счетчиком, достаточно импортировать useCounter в нужные модули, и использовать его.

Если необходимо ограничить доступ к переменной counter, можно экспортировать не ее, а функцию геттер:

import { ref, computed } from 'vue'

const counter = ref(0)
const getCounter = computed(() => counter.value)
const increment = () => counter.value++

export default function useCounter () {
  return { getCounter, increment }
}

За и против


Один из плюсов Vuex — работа с Vue.js devtools. Очень удобно видеть весь глобальный state в виде дерева, видеть вызовы mutations с переданными переменными, а также иметь возможность откатиться к разным состояниям. Как будет осуществляться поддержка composition API в Vue.js devtools пока не ясно, работа еще идет.

Структура Vuex — getters, mutations, actions может показаться синтаксически избыточной, но она позволяет ясно представлять и разделять работу модуля хранилища и скорее плюс, чем минус. А при использовании composition API разработчик сам все решает, может сделать конфетку, а может и нет.

Поддержка TypeScript это слабое место Vuex. Все статьи, где пытаются типизировать Vuex выглядят устрашающе. И так многословный Vuex становится очень многословным. Если же мы используем composition API — все проще, используйте TypeScript как обычно.

Vuex подключается как плагин, и доступен в каждом компоненте через this.$store. В случае с composition API нам надо импортировать модуль. Особой разницы нету, и тот и тот подход позволяют работать с глобальным состоянием.

Использование composition API зато избавляет нас от лишней зависимости и позволяет организовывать глобальное состояние так как удобно. С другой стороны остаётся вопрос тестирования. Сами глобальные модули тестировать легко, а вот модули их использующие уже тестировать сложнее.

Заключение


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