https://habr.com/ru/post/525038/- JavaScript
- VueJS
- TypeScript
Новый 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.