home / skills / pluginagentmarketplace / custom-plugin-vue / vue-pinia

vue-pinia skill

/skills/vue-pinia

This skill helps you master Pinia state management in Vue by guiding store design, actions, getters, plugins, and persistence.

npx playbooks add skill pluginagentmarketplace/custom-plugin-vue --skill vue-pinia

Review the files below or copy the command above to add this skill to your agents.

Files (6)
SKILL.md
6.0 KB
---
name: vue-pinia
description: Master Pinia State Management - Stores, Actions, Getters, Plugins, Persistence
sasmp_version: "1.3.0"
bonded_agent: 03-vue-pinia
bond_type: PRIMARY_BOND
version: "2.0.0"
last_updated: "2025-01"
---

# 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

```typescript
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:**
```typescript
// 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
- [ ] Create basic store with state
- [ ] Use storeToRefs in component
- [ ] Implement simple action
- [ ] Access getter value

### Intermediate Checkpoint
- [ ] Build async action with loading/error
- [ ] Create parameterized getter
- [ ] Compose two stores together
- [ ] Add persistence plugin

### Advanced Checkpoint
- [ ] Design normalized store structure
- [ ] Implement optimistic updates
- [ ] Create custom plugin
- [ ] Test stores in isolation

## Retry Logic

```typescript
const skillConfig = {
  maxAttempts: 3,
  backoffMs: [1000, 2000, 4000],
  onFailure: 'simplify_store_design'
}
```

## Observability

```yaml
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

1. Check Pinia devtools for state
2. Verify store ID is unique
3. Confirm pinia plugin is installed
4. Check for circular store imports

## Unit Test Template

```typescript
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: '[email protected]' })
    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

- [Pinia Documentation](https://pinia.vuejs.org/)
- [Pinia Best Practices](https://pinia.vuejs.org/cookbook/)
- [pinia-plugin-persistedstate](https://prazdevs.github.io/pinia-plugin-persistedstate/)

Overview

This skill teaches scalable Pinia state management for Vue apps, covering stores, actions, getters, plugins, and persistence. It focuses on practical patterns for store design, async flows, testing, and production concerns like persistence and observability. Learners finish able to design domain stores, implement plugins, and test stores in isolation.

How this skill works

The skill is organized into progressive modules: store fundamentals, actions and async handling, getters and computed state, store architecture, and plugins/persistence. Each module combines concise explanations, hands-on exercises, and validation checkpoints to verify learning outcomes. Built-in guidance covers retry/backoff strategies, event tracking for observability, and a unit test template for Vitest to ensure reliability.

When to use it

  • Setting up state management for small-to-large Vue apps.
  • Migrating from Vuex to a modern Pinia-based architecture.
  • Adding persistence or plugin logic (logging, reset, analytics).
  • Implementing async flows with loading/error handling and optimistic updates.
  • Enforcing a scalable domain-driven store structure for teams.

Best practices

  • Prefer setup-style defineStore for clearer reactivity and TypeScript support.
  • Organize stores by domain and re-export from a central index for discoverability.
  • Use storeToRefs to avoid losing reactivity when destructuring state in components.
  • Normalize large collections (ID maps) to improve performance and reduce duplication.
  • Add persistence selectively (auth/session) and avoid persisting volatile UI state.

Example use cases

  • Create a user store with login/logout, persisted auth, and a reset-on-logout plugin.
  • Build a product catalog with normalized state, parameterized getters, and cross-store composition for cart totals.
  • Implement async actions for fetching resources with loading/error states and optimistic updates for fast UX.
  • Add a logger plugin to trace actions during development and a persisted-state plugin for session continuity.
  • Write unit tests for stores using setActivePinia/createPinia and Vitest template to validate behavior in isolation.

FAQ

What level should I start at?

Begin with the beginner module to learn defineStore and component usage; progress to intermediate for async and persistence, then advanced for architecture and plugins.

How do I keep stores reactive when using them in components?

Use storeToRefs() before destructuring store state to preserve reactivity and avoid stale values.

Can I persist only part of a store?

Yes — configure the persistence plugin to whitelist/blacklist keys or create a custom serializer to persist selected state slices.