Published on

State management in Vue 3

Authors

Introduction

State management has been a large topic in the world of frontend. With involved libraries it can be a big task to set up state management, and picking the right one can feel overwhelming.

Vue 3 "primitives" like ref and reactive makes it easy to get started with state management, and the composition API makes it easy to scale.

So far, I have not needed a 3rd party library to build even large sites when using Vue 3.

The primitives

In the beginning of learning Vue 3 I had a hard time wrapping my head around when it can be smart to use either ref or reactive, but I think I've finally got it.

Usage

I always default to using ref in my Single File Components or Composables with simple values. When something smells like more complex state, that is used across multiple views or steps, I use reactive. This object is kept in a separate file, and imported into the components that need it. In simple use cases I mutate the values in the object directly. However, in larger use cases I prefer to add functions in the object to mutate the values, and then import these functions into the components that need them. Here is an example of a reactive object with functions:

import { reactive } from 'vue'

export const store = reactive({
  currentStep: 1,
  incrementStep() {
    this.currentStep++
  },
  decrementStep() {
    this.currentStep--
  },
})

Composables could come into play if I have more reactive values holding state that I would like to return in a co-located manner.

import { reactive } from 'vue'

const currentPageTitle = ref('Home')
const steps = reactive({
  currentStep: 1,
  incrementStep() {
    this.currentStep++
  },
  decrementStep() {
    this.currentStep--
  },
})

export function useStore() {
  return {
    steps,
    currentPageTitle,
  }
}

For more advanced state management the Vue 3 docs recommends using Pinia. It gives powerful features like:

  • Stronger conventions for team collaboration
  • Integrating with the Vue DevTools, including timeline, in-component inspection, and time-travel debugging
  • Hot Module Replacement
  • Server-Side Rendering support
  • TypeScript support

I haven't found a great need for Pinia, but I will be trying it out in the future.