Receber por email
← Voltar para o catálogo

pinia-v3

Pinia v3 Vue state management with defineStore, getters, actions. Use for Vue 3 stores, Nuxt SSR, Vuex migration, or encountering store composition, hydration, testing errors.

178estrelas
Atualizado há 5 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add secondsky/claude-skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/pinia-v3/svg)](https://www.skillteca.com.br/skills/pinia-v3)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Pinia v3 - Vue State Management

Status: Production Ready ✅ Last Updated: 2025-11-11 Dependencies: Vue 3 (or Vue 2.7 with @vue/composition-api) Latest Versions: pinia@^3.0.4, @pinia/nuxt@^0.11.2, @pinia/testing@^1.0.2

Quick Start (5 Minutes)

1. Install Pinia

bun add pinia
# or
bun add pinia
# or
bun add pinia

For Vue <2.7 users: Also install @vue/composition-api with bun add @vue/composition-api

Why this matters:

  • Pinia is the official Vue state management library
  • Provides better TypeScript support than Vuex
  • Eliminates mutations and namespacing complexity
  • Full DevTools support with time-travel debugging

2. Create and Register Pinia Instance

// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

CRITICAL:

  • Install Pinia BEFORE using any store
  • Call app.use(pinia) before mounting the app
  • Only one Pinia instance per application (unless SSR)

3. Define Your First Store

// stores/counter.ts
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
    name: 'Eduardo'
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    }
  }
})

4. Use Store in Components

<script setup>
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
</script>

<template>
  <div>
    <p>Count: {{ counter.count }}</p>
    <p>Double: {{ counter.doubleCount }}</p>
    <button @click="counter.increment">Increment</button>
  </div>
</template>

The Two Store Syntaxes

Load references/store-syntax-guide.md for complete comparison of Option vs Setup stores.

Quick Overview

Pinia supports two store definition syntaxes:

Option Stores:

  • Similar to Vue Options API
  • Built-in $reset() method
  • Best for: Simpler use cases, teams familiar with Vuex

Setup Stores:

  • Uses Composition API pattern
  • Full composables integration
  • Best for: Advanced patterns, need watchers/VueUse integration

→ Load references/store-syntax-guide.md for: Complete syntax comparison, examples, choosing criteria

State, Getters, and Actions

Load references/state-getters-actions.md for complete API reference.

Quick Reference

State:

  • Define in state: () => ({...}) (option) or ref() (setup)
  • Access directly: store.count
  • Mutate directly: store.count++ or store.$patch({...})
  • Reset: store.$reset() (option stores only)

Getters:

  • Computed properties: getters: { double: (state) => state.count * 2 }
  • Access other getters with this (must type return value)

Actions:

  • Business logic: actions: { increment() { this.count++ } }
  • Can be async
  • Access other stores directly

Store Destructuring:

import { storeToRefs } from 'pinia'

// ✅ For reactivity
const { name, count } = storeToRefs(store)

// ✅ Actions can destructure directly
const { increment } = store

→ Load references/state-getters-actions.md for: Complete API, subscriptions, store composition patterns, Options API usage

Plugins and Composables

Load references/plugins-composables.md for complete plugin and composables guide.

Plugin Basics

pinia.use(({ store, options }) => {
  // Add properties to every store
  return { customProperty: 'value' }
})

Composables Integration

Option Stores: Limited to useLocalStorage style in state() Setup Stores: Full VueUse/composables support

→ Load references/plugins-composables.md for: Complete plugin patterns, VueUse integration, TypeScript typing, common patterns (persistence, router, logger)

Using Stores Outside Components

The Problem

Stores need the Pinia instance, which is auto-injected in components but not available in module scope.

❌ Wrong: Accessing Store at Module Level

// router.ts
import { useUserStore } from '@/stores/user'

// ❌ Fails: Pinia not installed yet
const userStore = useUserStore()

router.beforeEach((to) => {
  if (userStore.isLoggedIn) { /* ... */ }
})

✅ Right: Accessing Store Inside Callbacks

// router.ts
import { useUserStore } from '@/stores/user'

router.beforeEach((to) => {
  // ✅ Works: Called after Pinia is installed
  const userStore = useUserStore()

  if (userStore.isLoggedIn) { /* ... */ }
})

Why it works: Router guards execute AFTER app.use(pinia) completes.

SSR: Explicit Pinia Instance

// server-side
export function setupRouter(pinia) {
  router.beforeEach((to) => {
    const userStore = useUserStore(pinia) // Pass explicitly
  })
}

Server-Side Rendering & Nuxt

Load references/ssr-and-nuxt.md for complete SSR and Nuxt integration guide.

SSR Quick Reference

State Hydration:

  • Server: Serialize with devalue() (not JSON.stringify)
  • Client: Hydrate BEFORE calling useStore()
  • Critical: Call all useStore() BEFORE await in actions

Nuxt 3/4 Integration

bunx nuxi@latest module add pinia

Auto-imports: defineStore, storeToRefs, usePinia, acceptHMRUpdate, all stores

→ Load references/ssr-and-nuxt.md for: Complete SSR patterns, Nuxt configuration, server-side data fetching, SSR pitfalls, debugging

Testing

Load references/testing-guide.md for complete testing guide.

Testing Quick Start

import { setActivePinia, createPinia } from 'pinia'

beforeEach(() => {
  setActivePinia(createPinia()) // Fresh Pinia for each test
})

Component Testing

bun add -d @pinia/testing
import { createTestingPinia } from '@pinia/testing'

mount(Component, {
  global: { plugins: [createTestingPinia()] }
})

→ Load references/testing-guide.md for: Complete test patterns, stubbing actions, mocking getters, async testing, SSR testing

Hot Module Replacement (HMR)

Vite Setup

// stores/counter.ts
import { defineStore, acceptHMRUpdate } from 'pinia'

export const useCounterStore = defineStore('counter', {
  // store definition
})

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot))
}

Webpack Setup

if (import.meta.webpackHot) {
  import.meta.webpackHot.accept(acceptHMRUpdate(useCounterStore, import.meta.webpackHot))
}

Benefits:

  • Edit stores without full page reload
  • Preserve application state during development
  • Faster development iteration

Options API Usage

For projects still using Options API, load complete mapper documentation.

→ Load references/state-getters-actions.md for: Complete Options API integration, all mappers (mapStores, mapState, mapWritableState, mapActions)

Migrating from Vuex

Load references/vuex-migration.md for complete migration guide.

Quick Conversion Overview

Key Changes:

  1. Remove namespaced (automatic via store ID)
  2. Eliminate mutations (direct state mutation)
  3. Replace commit() with direct mutations
  4. Replace rootState/rootGetters with store imports
  5. Use store.$reset() instead of custom clear mutations

Directory: store/modules/ → stores/ (each module = separate store)

→ Load references/vuex-migration.md for: Complete conversion steps, component migration, checklist, gradual migration strategy

Critical Rules

Always Do

✅ Define all state properties in state() or return them from setup stores ✅ Use storeToRefs() when destructuring state/getters in components ✅ Call app.use(pinia) BEFORE mounting the app ✅ Return all state from setup stores (private state breaks SSR/DevTools) ✅ Call useStore() inside functions/callbacks when used outside

Compartilhar X LinkedIn