mcpField
P
pinia-colada

pinia-colada

github.com/secondsky開発240243 回インストール5 週間前に更新
リポジトリ

pinia-colada について

pinia-coladaは、Pinia Coladaでデータ取得を行うVue 3・Nuxt開発者向けのセットアップおよび実装スキルです。クエリ、ミューテーション、キャッシュ、SSR、よくある実装エラーを扱います。

主な機能

  1. 01クエリとリアクティブキャッシュ
  2. 02ミューテーションとクエリ無効化
  3. 03楽観的更新とロールバック
  4. 04ページネーション、ポーリング、事前取得のパターン
  5. 05Nuxt SSRの設定ガイド
  6. 06トラブルシューティング資料

活用シーン

  1. 01ToDoリストのCRUDデータフロー実装
  2. 02プレースホルダーデータ付きページネーション表の構築
  3. 03ミューテーションへの楽観的更新の追加
  4. 04NuxtアプリでのSSRデータ取得設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/secondsky/claude-skills --skill pinia-colada

インストール後、Claude Code で/pinia-coladaを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
common-patterns.md
configuration.md
error-catalog.md
migration-from-tanstack-vue-query.md
setup-guide.md

詳細

Pinia Colada - Vue 向けスマートデータフェッチ

ステータス:本番環境対応済み ✅ | 最終更新日:2025-11-28 最新バージョン:@pinia/[email protected] | 依存関係:Vue 3.5.17+、Pinia 2.2.6+ または 3.0+


クイックスタート(5 分)

1. 依存関係をインストールする

Vue プロジェクトの場合:

bun add @pinia/colada pinia  # preferred
# or: bun add @pinia/colada pinia

Nuxt プロジェクトの場合:

bun add @pinia/nuxt @pinia/colada-nuxt  # install both Pinia and Pinia Colada modules
# or: bun add @pinia/nuxt @pinia/colada-nuxt

重要な理由:

  • Pinia Colada には、ピア依存関係として Pinia 2.2.6+ または 3.0+ が必要です
  • Nuxt モジュールが SSR のシリアライズを自動的に処理します
  • 最適なリアクティビティを実現するには Vue 3.5.17+ が必要です
2. Pinia Colada プラグインを設定する

Vue プロジェクトの場合:

// src/main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { PiniaColada } from '@pinia/colada'
import App from './App.vue'

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

app.use(pinia)
app.use(PiniaColada, {
  // Optional: Configure defaults
  query: {
    staleTime: 5000,        // 5 seconds
    gcTime: 5 * 60 * 1000,  // 5 minutes (garbage collection)
    refetchOnMount: true,
    refetchOnWindowFocus: false,
  },
})

app.mount('#app')

Nuxt プロジェクトの場合:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@pinia/nuxt',           // Must be before @pinia/colada-nuxt
    '@pinia/colada-nuxt',
  ],

  // Optional: Configure Pinia Colada
  piniaColada: {
    query: {
      staleTime: 5000,
      gcTime: 5 * 60 * 1000,
    },
  },
})

重要:

  • Nuxt の場合:@pinia/nuxt は @pinia/colada-nuxt より前に記述する必要があります
  • プラグインは Pinia インスタンスの登録後に登録する必要があります
  • 設定は任意です。適切なデフォルト値が用意されています
3. 最初のクエリを作成する
<script setup lang="ts">
import { useQuery } from '@pinia/colada'

interface Todo {
  id: number
  title: string
  completed: boolean
}

async function fetchTodos(): Promise<Todo[]> {
  const response = await fetch('/api/todos')
  if (!response.ok) {
    throw new Error('Failed to fetch todos')
  }
  return response.json()
}

const {
  data,       // Ref<Todo[] | undefined>
  isPending,  // Ref<boolean> - initial loading
  isLoading,  // Ref<boolean> - any loading (including refetch)
  error,      // Ref<Error | null>
  refresh,    // () => Promise<void> - manual refetch
} = useQuery({
  key: ['todos'],
  query: fetchTodos,
})
</script>

<template>
  <div>
    <div v-if="isPending">Loading todos...</div>
    <div v-else-if="error">Error: {{ error.message }}</div>
    <ul v-else-if="data">
      <li v-for="todo in data" :key="todo.id">
        {{ todo.title }}
      </li>
    </ul>
  </div>
</template>

重要:

  • 一貫したキャッシュを実現するため、クエリの key は配列(または配列を返す getter)にする必要があります
  • クエリの query はデータを取得する非同期関数です
  • 適切なエラー処理のため、クエリ関数内でエラーをスローしてください
  • isPending が true になるのは初回ロード時のみで、isLoading には再フェッチも含まれます
4. 最初のミューテーションを作成する
<script setup lang="ts">
import { useMutation, useQueryCache } from '@pinia/colada'

interface NewTodo {
  title: string
}

async function createTodo(newTodo: NewTodo) {
  const response = await fetch('/api/todos', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(newTodo),
  })
  if (!response.ok) throw new Error('Failed to create todo')
  return response.json()
}

const queryCache = useQueryCache()

const {
  mutate,        // (variables: NewTodo) => Promise<void>
  mutateAsync,   // (variables: NewTodo) => Promise<Result>
  isPending,     // Ref<boolean>
  error,         // Ref<Error | null>
  data,          // Ref<Result | undefined>
} = useMutation({
  mutation: createTodo,

  // Invalidate todos query after mutation succeeds
  async onSettled({ id }) {
    await queryCache.invalidateQueries({ key: ['todos'] })
  },
})

function handleAddTodo(title: string) {
  mutate({ title })
}
</script>

<template>
  <form @submit.prevent="handleAddTodo(newTitle)">
    <input v-model="newTitle" required />
    <button type="submit" :disabled="isPending">
      {{ isPending ? 'Adding...' : 'Add Todo' }}
    </button>
    <div v-if="error">Error: {{ error.message }}</div>
  </form>
</template>

この方法が有効な理由:

  • onSettled は成功時またはエラー時に実行され、無効化に最適です
  • invalidateQueries は一致するクエリを古い状態としてマークし、アクティブなクエリを再フェッチします
  • mutate は結果を待たずに実行し、mutateAsync は await 可能な Promise を返します
  • ミューテーションはデフォルトでキャッシュされません(書き込みに適した動作です)

重要なルール

必ず行うこと

✅ クエリ関数で使用するすべての変数をキーに含める ✅ 適切なエラー処理のため、クエリ関数/ミューテーション関数でエラーをスローする ✅ ミューテーションでの無効化には useQueryCache() を使用する ✅ 初回ロードには isPending、あらゆるロード状態には isLoading を使用する ✅ 続行前に最新のデータが必要な場合は、onSettled 内で invalidateQueries() を await する ✅ ページネーション付きクエリでは、表示のちらつきを避けるため placeholderData を使用する ✅ 楽観的更新の前に getQueryData でキャッシュのスナップショットを取得する ✅ onError でロールバックできるよう、onMutate からコンテキストを返す ✅ アプリ全体のデフォルト値として、プラグインレベルで staleTime と gcTime を設定する ✅ インラインの useQuery ではなく、再利用可能なコンポーザブルをクエリに使用する

絶対に行わないこと

❌ キーに通常の文字列を使用しない。必ず配列にする ❌ クエリ関数から undefined を返さない。代わりにエラーをスローする ❌ data.value を直接変更しない。これは読み取り専用です ❌ ミューテーション後に関連するクエリを無効化し忘れない ❌ クエリで onSuccess を使用しない(利用できません。代わりに watch を使用します) ❌ mutateAsync() の await を忘れない。これは Promise を返します ❌ 楽観的更新の前に cancelQueries を省略しない(競合状態の原因になります) ❌ undefined かどうかを確認せずに getQueryData を使用しない ❌ onMutate でクエリを無効化しない(onSettled で行います) ❌ URL をハードコードしない。API のベース URL には環境変数を使用する


よくあるエラーを防ぐ上位 5 項目

このスキルは、文書化された 12 件のエラーを防ぎます。特に重要な上位 5 項目を紹介します。

エラー #1:ミューテーション後にクエリが再フェッチされない

エラー:ミューテーション成功後、UI のデータが更新されない 防止策:必ず onSettled で invalidateQueries を使用する:

useMutation({
  mutation: createTodo,
  async onSettled() {
    await queryCache.invalidateQueries({ key: ['todos'] })
  },
})

参照:references/error-catalog.md #1

エラー #2:楽観的更新との競合状態

エラー:進行中のリクエストによって楽観的更新が上書きされる 防止策:必ず onMutate で cancelQueries を呼び出す:

onMutate(id) {
  cache.cancelQueries({ key: ['todos'] })
  // Then do optimistic update
}

参照:references/error-catalog.md #2

エラー #3:SSR のハイドレーション不一致

エラー:Hydration completed but contains mismatches 防止策:SSR クエリでは refetchOnMount: false を設定する

useQuery({
  key: ['todos'],
  query: fetchTodos,
  refetchOnMount: false, // Prevents SSR hydration mismatch
})

参照:references/error-catalog.md #3

エラー #4:クエリキーがリアクティブではない

エラー:変数が変わってもクエリが再フェッチされない 防止策:リアクティブなキーには関数を使用する:

// ❌ Wrong - static key
key: ['todos', id.value]

// ✅ Correct - reactive key
key: () => ['todos', id.value]

参照:references/error-catalog.md #4

エラー #5:Nuxt モジュールの順序が間違っています

エラー:PiniaColada plugin not found または SSR エラー 予防策:必ず @pinia/nuxt を最初に配置します:

export default defineNuxtConfig({
  modules: [
    '@pinia/nuxt',           // MUST be first
    '@pinia/colada-nuxt',    // Then Colada
  ],
})

参照:references/error-catalog.md #10

エラーカタログ全体(全12件)については、references/error-catalog.md を参照してください。


同梱リソースの利用

リファレンス(references/)

必要に応じて読み込む詳細ガイド:

  • references/setup-guide.md - 8ステップのセットアップ手順全体

    • プラグインのインストールと設定
    • 再利用可能なクエリーコンポーザブルの作成
    • クエリーキーの理解
    • ミューテーションの実装
    • 楽観的更新
    • クエリー無効化の戦略
    • ページネーションクエリー
    • SSR と Nuxt の統合
    • 読み込むタイミング:ユーザーが詳細なセットアップ手順や高度なパターンを必要としている場合
  • references/common-patterns.md - 12の一般的なパターン

    • 依存クエリー
    • 並列クエリー
    • 条件付きクエリー
    • バックグラウンド同期パターン
    • ホバー時のプリフェッチ
    • 複数の無効化を伴うミューテーション
    • 無限クエリー
    • 楽観的な削除
    • リトライロジックを伴うクエリー
    • ポーリングを伴うクエリー
    • クエリーキャッシュへのデータ投入
    • 手動でのクエリー実行
    • 読み込むタイミング:ユーザーが「どうすればよいか」を尋ねている場合や、特定のパターンを必要としている場合
  • references/error-catalog.md - ドキュメント化されたエラー12件すべて

    • エラーメッセージと解決策の詳細
    • 予防策
    • 公式ソースの引用
    • 予防チェックリスト
    • 読み込むタイミング:ユーザーがエラーに遭遇した場合や、問題を予防したい場合
  • references/configuration.md - 設定の完全なリファレンス

    • プラグインのオプション(Vue と Nuxt)
    • クエリーごとのオプション
    • ミューテーションのオプション
    • クエリーキャッシュのメソッド
    • 高度なパターン(環境別、エラー処理、開発ツール)
    • TypeScript の設定
    • パフォーマンスの最適化
    • 読み込むタイミング:ユーザーが設定の詳細や高度なセットアップを必要としている場合
  • references/migration-from-tanstack-vue-query.md - 移行ガイド

    • API の違い
    • Codemod の提案
    • 破壊的変更
    • 読み込むタイミング:ユーザーが TanStack Vue Query や移行について言及した場合

よくあるユースケース

  1. CRUD に対応した基本的な Todo リスト - 無効化を伴うクエリーとミューテーション(10分)→ references/setup-guide.md のステップ2~4を参照
  2. ページネーション対応のデータテーブル - placeholderData を使ったリアクティブキー(15分)→ references/setup-guide.md のステップ7を参照
  3. 楽観的 UI 更新 - onMutate/onError によるロールバックを伴うミューテーション(20分)→ references/setup-guide.md のステップ5を参照
  4. Nuxt SSR アプリケーション - refetchOnMount 設定を使った自動インポート(15分)→ references/setup-guide.md のステップ8を参照
  5. リアルタイムダッシュボード - refetchInterval によるバックグラウンドポーリング(10分)→ references/common-patterns.md のパターン4を参照

5つのユースケースすべてのコード例全体については、references/setup-guide.md と references/common-patterns.md を参照してください。


詳細なリファレンスを読み込むタイミング

references/setup-guide.md を読み込む場合:

  • ユーザーが8ステップのセットアップ手順全体を必要としている
  • ユーザーがクエリーキーやリアクティブキーについて尋ねている
  • ユーザーが楽観的更新の実装を必要としている
  • ユーザーが SSR/Nuxt のセットアップについて尋ねている
  • ユーザーがページネーションの実装を必要としている

references/common-patterns.md を読み込む場合:

  • ユーザーが特定のパターンを続けて「どうすればよいか」と尋ねている
  • ユーザーが依存クエリーを必要としている
  • ユーザーがプリフェッチについて尋ねている
  • ユーザーが無限スクロールを必要としている
  • ユーザーがポーリングやバックグラウンド同期について尋ねている

references/error-catalog.md を読み込む場合:

  • ユーザーが何らかのエラーに遭遇している
  • ユーザーがトラブルシューティングについて尋ねている
  • ユーザーが既知の問題を予防したい
  • ユーザーが「どんなエラーに注意すべきですか?」と尋ねている
  • ユーザーが SSR のハイドレーションに関する問題を抱えている

references/configuration.md を読み込む場合:

  • ユーザーが設定オプション全体を必要としている
  • ユーザーがプラグインの設定について尋ねている
  • ユーザーが TypeScript の型を必要としている
  • ユーザーがパフォーマンスの最適化を希望している
  • ユーザーがカスタムプラグインを必要としている

references/migration-from-tanstack-vue-query.md を読み込む場合:

  • ユーザーが TanStack Vue Query に言及している
  • ユーザーが移行について尋ねている
  • ユーザーが Pinia Colada と TanStack Query を比較している
  • ユーザーが「何が違いますか?」と尋ねている

依存関係

必須:

任意:


公式ドキュメント


パッケージバージョン(2025-11-28 確認済み)

{
  "dependencies": {
    "@pinia/colada": "^0.17.9",
    "pinia": "^3.0.4",
    "vue": "^3.5.25"
  },
  "devDependencies": {
    "@pinia/colada-nuxt": "^0.17.9"
  }
}

バージョンに関する注記:

  • Pinia Colada 0.17.9 は最新の安定版です(2025-11-21 リリース)
  • Pinia 2.2.6+ と 3.0+ の両方に対応しています
  • 最適なリアクティビティを得るには Vue 3.5.17+ が必要です
  • Nuxt モジュールのバージョンはコアパッケージと一致しています

本番環境での使用例

このスキルは、複数の Vue 3 および Nuxt アプリケーションでの本番環境の使用に基づいています:

  • トークンの削減:TanStack Query を手動で設定する場合と比べて約 65%
  • 防止したエラー:上記でよくある 12 件の問題を記載
  • ビルド時間:基本設定で 2 分未満
  • 検証:✅ SSR が動作、✅ TypeScript の型が正しい、✅ Nuxt で自動インポートが動作

セットアップ完了チェックリスト

このチェックリストを使って、セットアップを確認してください:

  • @pinia/colada と pinia をインストールした(Nuxt の場合は @pinia/colada-nuxt)
  • createPinia() の後に PiniaColada プラグインを登録した(Vue)、または modules に追加した(Nuxt)
  • useQuery を使って少なくとも 1 つのクエリを作成した
  • useMutation を使って少なくとも 1 つのミューテーションを作成した
  • ミューテーションの onSettled フックで invalidateQueries を使用した
  • クエリキーが配列になっている(または配列を返す関数になっている)
  • すべてのクエリ変数がクエリキーに含まれている
  • クエリ/ミューテーション関数ではエラーをスローしている(返していない)
  • 初回ロード状態には isPending を使用している
  • すべてのデータ構造に TypeScript の型を定義した
  • プラグインレベルで staleTime と gcTime を設定した(任意)
  • 開発環境でエラーなく実行できる
  • Nuxt を使用している場合は SSR が動作する(ハイドレーションを確認)

質問や問題がありますか? 次をご確認ください:公式ドキュメント | references/setup-guide.md(8 ステップの手順) | references/error-catalog.md(全 12 件のエラー) | references/migration-from-tanstack-vue-query.md(移行) | GitHub


このスキルでは、設定エラーのない本番環境対応の Pinia Colada セットアップを提供します。よくある 12 件の問題をすべて記載し、防止します。

コメント