VueJS 3: Global State with Composition API





The new Composition API lets you get rid of the Vuex store. Let's look at a simple example of how to achieve this. And consider the pros and cons.



Example



Let's take a sample counter in Vuex from the-simplest-store documentation and implement it using the composition API.



Counter module modules / counter.ts:



import { ref } from 'vue'

const counter = ref(0)

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


Note that the counter variable is outside the useCounter () function. Thus, when the useCounter function is called in different components, counter will refer to the same instance. And this is what we need.



Using our counter in different components is simple:



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


To use the global counter, you just need to import useCounter into the required modules and use it.



If you need to restrict access to the counter variable, you can export not it, but the getter function:



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


Pros and cons



One of the great things about Vuex is working with Vue.js devtools. It is very convenient to see the entire global state in the form of a tree, to see the calls to mutations with the passed variables, and also to be able to roll back to different states. How the composition API will be supported in Vue.js devtools is not yet clear, work is still in progress.



Vuex's structure - getters, mutations, actions - might sound syntactically redundant, but it allows for a clear presentation and separation of the storage module's work and is more of a plus than a minus. And when using the composition API, the developer decides everything himself, he can make a candy, or maybe not.



TypeScript support is a weak point in Vuex. All articles trying to type Vuex look intimidating. And that's how verbose Vuex becomes very verbose. If we're using the composition API, it's simpler, use TypeScript as usual.



Vuex connects as a plugin and is available in every component via this. $ Store. In the case of the composition API, we need to import the module. There is not much difference, and both approaches allow you to work with global state.



Using the composition API, on the other hand, relieves us of unnecessary dependencies and allows us to organize the global state as it is convenient. On the other hand, the question of testing remains. The global modules themselves are easy to test, but the modules using them are already more difficult to test.



Conclusion



It's not clear yet whether it's worth abandoning Vuex, but there is definitely a new tool that allows you to solve the problems solved by Vuex. It will be clear soon which approach is better, and in which case. In the meantime, the Vuex developers have not announced about the project folding and saw it as before, and in the Vue3 documentation there is still a link to Vuex.



All Articles