Новый 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.
Spunreal
Composition API не решает задачи Vuex'а. Они совершенно о разном. Vuex о централизованном хранилище, а Composition API об организации логики и кода в компонентах. Без Vuex'а и во Vue 2 можно было обойтись. Даже в документации пример простого хранилища есть. А все эти
mapState
,mapGetters
и т.п. во Vuex 4 как раз построены на Composition API.Пока мы используем только счётчик — всё хорошо, нам Vuex не нужен ни во Vue 3, ни во Vue 2. А как нужно большое централизованное хранилище как источник истины с поддержкой модулей, так либо Vuex, либо другое такое же большое решение (может кто-то захочет Mobx прикрутить, кто знает), либо свой велосипед.
Если выбирать между Vuex или своим велосипедом, то лучше выбрать Vuex.
Almatyn Автор
Вот в том-то и вопрос. Что лучше выбрать. Да, понимаю, пример со счетчиком выглядит не очень убедительно, но он демонстрирует принцип. В целом данный подход позволяет делать большое централизованное хранилище как источник истины. Также как и модули Vuex вы можете организовать свои модули, сколь угодно сложные. Реактивность поддерживается. Возможность обратиться из любого компонента, и не только, имеется.