LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 3416 min read

Pinia Actions, Getters & Stores

Organize a Pinia store with the Options-style syntax, understand getters vs actions, and compose stores together.

The Options-Style Store

Alongside the setup-store syntax from the previous lesson, Pinia also supports an Options-style definition, structured similarly to the Options API — many teams find this form especially readable for stores.

// stores/cart.js
import { defineStore } from 'pinia';
export const useCartStore = defineStore('cart', {
state: () => ({
items: [],
}),
getters: {
totalPrice: (state) => state.items.reduce((sum, item) => sum + item.price, 0),
},
actions: {
addItem(item) {
this.items.push(item);
},
removeItem(id) {
this.items = this.items.filter((item) => item.id !== id);
},
},
});

State, Getters, and Actions Explained

BlockPurposeComposition API Equivalent
stateThe store's raw reactive dataref() / reactive()
gettersCached, derived values from statecomputed()
actionsMethods that read and mutate state, sync or asyncplain functions

Async Actions

Actions can be async functions directly — Pinia has no special API for this; it's just a plain async method using this to access and mutate state.

actions: {
async fetchCart() {
const res = await fetch('/api/cart');
this.items = await res.json();
},
},

Using One Store Inside Another

A store can call another store's composable inside its own actions — a common pattern when, say, a cart store needs to check the current user from a user store.

import { useUserStore } from './user';
export const useCartStore = defineStore('cart', {
actions: {
async checkout() {
const userStore = useUserStore();
if (!userStore.isLoggedIn) {
throw new Error('Must be logged in to checkout');
}
// ... proceed with checkout
},
},
});

Common Beginner Mistakes

Using an arrow function for an action that needs `this`

Arrow functions don't bind their own this, so this.items inside one would be undefined — use a regular method shorthand (addItem(item) { ... }) for actions.

Mutating state directly from a component instead of through an action

It technically works, but funneling all mutations through actions keeps state changes traceable and centralized — especially valuable as a store grows.

FAQs

Both are fully supported and equally valid; the setup-store syntax is a bit more flexible (it can use any Composition API feature directly), while the Options-style is often considered clearer for simple stores.

Yes — getters are cached based on their dependencies, exactly like a computed property, and only recompute when the underlying state they read changes.

Summary

The Options-style store organizes state, getters, and actions explicitly, and stores can call one another cleanly. With routing and state management covered, the next section turns to data fetching and forms.

Next Lesson →

Fetching Data