Vue Pinia Skill
Production-grade skill for mastering Pinia state management in Vue applications.
Purpose
Single Responsibility: Teach scalable state management patterns with Pinia including store design, actions, getters, plugins, and persistence strategies.
Parameter Schema
interface PiniaParams {
topic: 'stores' | 'actions' | 'getters' | 'plugins' | 'persistence' | 'all';
level: 'beginner' | 'intermediate' | 'advanced';
context?: {
app_size?: 'small' | 'medium' | 'large';
existing_state?: string[];
};
}
Learning Modules
Module 1: Store Fundamentals
Prerequisites: vue-composition-api
Duration: 2-3 hours
Outcome: Create and use Pinia stores
| Topic |
Concept |
Exercise |
| Setup |
Install and configure |
App setup |
| defineStore |
Create stores |
Counter store |
| State |
Reactive state |
User store |
| Using stores |
storeToRefs |
Component access |
Store Syntax Comparison:
// Options Store
defineStore('counter', {
state: () => ({ count: 0 }),
getters: { double: (s) => s.count * 2 },
actions: { increment() { this.count++ } }
})
// Setup Store (Recommended)
defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() { count.value++ }
return { count, double, increment }
})
Module 2: Actions & Async
Prerequisites: Module 1
Duration: 2-3 hours
Outcome: Handle async operations
| Pattern |
Use Case |
Exercise |
| Sync actions |
Simple mutations |
Cart updates |
| Async actions |
API calls |
Fetch users |
| Error handling |
Try/catch |
Error states |
| Loading states |
UX feedback |
Spinners |
| Optimistic updates |
Fast UX |
Instant feedback |
Module 3: Getters & Computed
Prerequisites: Module 2
Duration: 1-2 hours
Outcome: Derive and filter state
| Pattern |
Use Case |
Exercise |
| Simple getter |
Derived value |
Full name |
| Parameterized |
Filtered access |
Find by ID |
| Cross-store |
Compose stores |
Cart with products |
| Memoization |
Performance |
Expensive calcs |
Module 4: Store Architecture
Prerequisites: Modules 1-3
Duration: 3-4 hours
Outcome: Design scalable store structure
Architecture Patterns:
stores/
├── modules/
│ ├── useUserStore.ts # User domain
│ ├── useProductStore.ts # Product domain
│ └── useCartStore.ts # Cart domain
├── shared/
│ └── useNotificationStore.ts
└── index.ts # Re-exports
| Pattern |
Description |
When to Use |
| Domain stores |
One per feature |
Large apps |
| Composed stores |
Store uses store |
Related data |
| Normalized state |
ID-based lookup |
Many entities |
| Module pattern |
Organized exports |
Team projects |
Module 5: Plugins & Persistence
Prerequisites: Modules 1-4
Duration: 2-3 hours
Outcome: Extend Pinia functionality
| Plugin |
Function |
Exercise |
| Logger |
Dev debugging |
Action logging |
| Persisted State |
LocalStorage |
Auth persistence |
| Reset |
State reset |
Logout cleanup |
| Custom |
Domain-specific |
Analytics |
Validation Checkpoints
Beginner Checkpoint
Intermediate Checkpoint
Advanced Checkpoint
Retry Logic
const skillConfig = {
maxAttempts: 3,
backoffMs: [1000, 2000, 4000],
onFailure: 'simplify_store_design'
}
Observability
tracking:
- event: store_created
data: [store_name, store_type]
- event: pattern_applied
data: [pattern_name, success]
- event: skill_completed
data: [stores_built, complexity]
Troubleshooting
Common Issues
| Issue |
Cause |
Solution |
| Store not reactive |
Destructured state |
Use storeToRefs() |
| Circular dependency |
A→B→A imports |
Lazy import or reorganize |
| No active Pinia |
Used before app.use |
Check setup order |
| HMR not working |
Missing acceptHMRUpdate |
Add HMR config |
Debug Steps
- Check Pinia devtools for state
- Verify store ID is unique
- Confirm pinia plugin is installed
- Check for circular store imports
Unit Test Template
import { describe, it, expect, beforeEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useUserStore } from './useUserStore'
describe('useUserStore', () => {
beforeEach(() => {
setActivePinia(createPinia())
})
it('initializes with null user', () => {
const store = useUserStore()
expect(store.user).toBeNull()
})
it('logs in user correctly', async () => {
const store = useUserStore()
await store.login({ email: 'test@example.com' })
expect(store.isLoggedIn).toBe(true)
})
it('logs out and clears state', () => {
const store = useUserStore()
store.$patch({ user: { id: '1', name: 'Test' } })
store.logout()
expect(store.user).toBeNull()
})
})
Usage
Skill("vue-pinia")
Related Skills
vue-composition-api - Prerequisite
vue-typescript - Typed stores
vue-testing - Store testing
Resources