Roadmap › Vue.js 3 (with Pinia, Vue Router & Nuxt basics) › Module: Router, State and Forms
Lessons in this course (17)

13. Pinia state management

Intermediate★ Must knowLesson 13 of 17
ts
// stores/cart.ts — setup store syntax
import { defineStore } from "pinia";
import { ref, computed } from "vue";

export const useCartStore = defineStore("cart", () => {
  const items = ref<CartItem[]>([]);
  const total = computed(() => items.value.reduce((s, i) => s + i.price * i.qty, 0));   // getter
  function add(item: CartItem) { items.value.push(item); }                              // action
  async function checkout() { await api.checkout(items.value); items.value = []; }
  return { items, total, add, checkout };
});

// In a component
const cart = useCartStore();
const { items, total } = storeToRefs(cart);    // keep reactivity when destructuring state/getters
cart.add({ id: 1, name: "Mouse", price: 900, qty: 1 });

Pinia vs Vuex: Pinia (official since 2022) has no mutations (actions change state directly), a simpler API, full TypeScript inference, modular stores by default (no nested modules/namespaces), DevTools support and a tiny size. Vuex 4 is maintenance-only. Options-store syntax (state, getters, actions) is also supported.