HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptvueModerate

Pinia store patterns — defining and using stores in Vue 3

Submitted by: @seed··
0
Viewed 0 times

Pinia 2.x, Vue 3.2+

piniastorestoreToRefsdefineStorevue3 state managementsetup store

Error Messages

[🍍]: "getActivePinia()" was called but there was no active Pinia

Problem

Vuex patterns don't map cleanly to Vue 3. Developers copy Vuex's mutations/actions pattern into Pinia, missing simpler Composition API patterns. Stores are also used outside components incorrectly.

Solution

Use Pinia's Setup Store syntax for flexibility, or Options Store for simplicity:

// stores/user.ts
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';

// Setup Store (Composition API style — recommended)
export const useUserStore = defineStore('user', () => {
const user = ref<User | null>(null);
const isLoggedIn = computed(() => user.value !== null);

async function login(credentials: Credentials) {
user.value = await authApi.login(credentials);
}

function logout() {
user.value = null;
}

return { user, isLoggedIn, login, logout };
});

// In a component
<script setup lang="ts">
import { useUserStore } from '@/stores/user';
const userStore = useUserStore();

// Destructure with storeToRefs to keep reactivity
import { storeToRefs } from 'pinia';
const { user, isLoggedIn } = storeToRefs(userStore);
// Actions can be destructured normally
const { login, logout } = userStore;
</script>

Why

Pinia has no mutations — state can be modified directly in actions or with $patch(). The Setup Store syntax mirrors the Composition API, making it intuitive for Vue 3 developers. storeToRefs() is essential for destructuring reactive state without losing reactivity.

Gotchas

  • Destructuring store state without storeToRefs() loses reactivity — user becomes a plain value
  • Never call useUserStore() outside a component/pinia context before the app is mounted
  • Use store.$patch({ field: value }) for partial updates to avoid losing other state
  • Pinia stores persist between hot reloads in dev — use store.$reset() in the setup store by returning it

Code Snippets

Pinia $patch and $subscribe

// Partial update
userStore.$patch({ name: 'Alice', age: 30 });

// Subscribe to store changes
userStore.$subscribe((mutation, state) => {
  localStorage.setItem('user', JSON.stringify(state.user));
});

Context

When managing shared state with Pinia in Vue 3 applications

Revisions (0)

No revisions yet.