SkillByAIOpen interactive version →

Lesson 19 / 25

Pinia Stores

Shared state with getters and actions.

The official store library

Pinia is the official state management library for Vue, replacing Vuex for new projects. A store is defined with defineStore(id, ...) and installed with app.use(createPinia()). In a setup store, the function body uses Composition API pieces: refs become state, computed values become getters and functions become actions, and you return everything that should be public. An option store uses state, getters and actions objects instead. Components call useXStore() to get the store instance. Destructuring the store directly loses reactivity for state and getters; use storeToRefs(store) for those, while actions can be destructured directly. Pinia also integrates with Vue Devtools.

Shared state and server data

Pinia stores hold shared client state, data-fetching patterns handle server state, and TypeScript keeps both safe.

Figure 7.1 — Stores, server data and types.

A cart setup store and its use

stores/cart.js and a component.

// stores/cart.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCartStore = defineStore('cart', () => {
  const items = ref([])                                   // state
  const count = computed(() => items.value.length)         // getter
  const total = computed(() => items.value.reduce((s, i) => s + i.price, 0))

  function add(product) { items.value.push(product) }      // action
  function clear() { items.value = [] }

  return { items, count, total, add, clear }
})

// main.js: app.use(createPinia())

// In a component's <script setup>:
// import { storeToRefs } from 'pinia'
// import { useCartStore } from '@/stores/cart'
// const cart = useCartStore()
// const { count, total } = storeToRefs(cart)   // keep reactivity
// const { add } = cart                         // actions are fine to destructure

Keep server data out of global stores when you can

Stores are ideal for client state such as the cart, the current user or UI preferences. Cached server data with refetching is often better handled by a data-fetching library.

Quick check: Why use storeToRefs when destructuring a Pinia store?

  • To register the store with the router
  • To make actions run faster
  • To persist the store to localStorage
  • To keep state and getters reactive after destructuring
Answer

To keep state and getters reactive after destructuring — Plain destructuring copies values.