pinia-colada-skilld について
pinia-colada-skilld は、Pinia を基盤とする Vue 向けデータ取得レイヤー @pinia/colada のリファレンススキルです。キャッシュ付きクエリ、ミューテーション、共有クエリ状態、キャッシュ管理を Vue 開発者向けに解説します。
主な機能
- 01リアクティブなキーによるキャッシュ付きクエリ
- 02ミューテーションとクエリの無効化
- 03defineQuery によるクエリ状態の共有
- 04再利用可能な型付きクエリオプション
- 05キャッシュ管理と無限クエリ
活用シーン
- 01ルートパラメーターに応じたデータ取得
- 02ミューテーション後のキャッシュクエリ更新
- 03コンポーネント間でのクエリ状態の共有
- 04ページ分割されたデータ表示の構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ skilld-dev/ vue-ecosystem-skills --skill pinia-colada-skilldインストール後、Claude Code で/pinia-colada-skilldを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/infinite-queries.mdmigration.mdmutations.mdplugins.mdqueries.mdquery-cache.mdssr.md詳細
@pinia/colada 1.4.5
Pinia を基盤とする、Vue.js 向けのスマートなデータフェッチレイヤーです。クエリはデータを読み取り、キャッシュします(useQuery)。ミューテーションはデータを書き込み(useMutation)、すべて Pinia ストアに保存されます(useQueryCache、useMutationCache)。
- ドキュメント:https://pinia-colada.esm.dev
- API 型:準備済みパッケージソース内の
dist/index.d.mts - ランタイムエクスポート:
dist/index.mjs:1487 - ピア依存関係:
vue ^3.5.41、pinia ^2.2.6 || ^3.0.0 || ^4.0.2(pinia 4 は 1.4.1 以降で使用可能、package.json:91-94) - 同梱 codemod:パッケージ内の
codemods/rules/*.yaml
セットアップ
npm install pinia @pinia/colada
import { createPinia } from 'pinia'
import { PiniaColada } from '@pinia/colada'
const app = createApp(App)
app.use(createPinia())
// install after pinia; the options object is required for correct typing
app.use(PiniaColada, {
queryOptions: { staleTime: 60_000 },
plugins: [],
})
グローバルオプションは queryOptions / mutationOptions に設定します(dist/index.d.mts:1601-1618)。
基本的な考え方
- クエリは
keyで識別します。これは JSON シリアライズ可能な配列です (EntryKey、dist/index.d.mts:119)。キーは階層構造になっており、フィルタリング時には{ key: ['todos'] }が['todos', { filter: 'done' }]にも一致します。 statusはデータの状態です:'pending' | 'success' | 'error'。asyncStatusは操作の状態です:'idle' | 'loading'。意図的に別々になっています (https://pinia-colada.esm.dev/guide/queries.md)。- デフォルト値:
staleTime: 5000、gcTime: 300_000、refetchOnMount、refetchOnWindowFocus、refetchOnReconnect、enabled: true(dist/index.mjs:92-97)。ミューテーションのgcTimeのデフォルト値は60_000です (dist/index.d.mts:1379)。
主なパターン
基本的なクエリ
<script setup lang="ts">
import { useQuery } from '@pinia/colada'
const { state, asyncStatus } = useQuery({
key: ['todos'],
query: () => fetch('/api/todos').then(res => res.json()),
})
</script>
<template>
<div v-if="state.status === 'pending'">Loading...</div>
<div v-else-if="state.status === 'error'">{{ state.error.message }}</div>
<ul v-else>
<li v-for="todo in state.data" :key="todo.id">{{ todo.text }}</li>
</ul>
</template>
テンプレートで型を絞り込むには、グループ化された state オブジェクトを使用します。TypeScript は status から個別の data / error 参照を絞り込めません
(https://pinia-colada.esm.dev/guide/queries.md)。
リアクティブなキー:ゲッターを渡す
query 関数が読み取るすべての値(ルートパラメーター、ref)は、key に含める必要があります。
依存関係の変更時にクエリが再フェッチされるよう、key はゲッターとして渡します。
const { data } = useQuery({
key: () => ['contacts', route.params.id as string],
query: () => fetch(`/api/contacts/${route.params.id}`).then(r => r.json()),
})
enabled でクエリを制御する
必要なパラメーターがない場合に無効なフェッチを防ぎます(ストアやグローバルクエリでよく使われます)。
useQuery({
key: () => ['decks', route.params.deckId],
query: () => fetchDeck(route.params.deckId as string),
enabled: () => 'deckId' in route.params,
})
型安全な共有オプション:defineQueryOptions
export const todoOptions = defineQueryOptions((id: string) => ({
key: ['todos', id],
query: () => fetchTodo(id),
}))
// single-function form; the returned key is tagged so queryCache infers TData
const { data } = useQuery(() => todoOptions(route.params.id as string))
const todo = queryCache.getQueryData(todoOptions('1').key) // typed
useQuery はオプション、またはオプションを返すゲッターを受け取ります
(dist/index.d.mts:733)。1.0 以降、2 つのパラメーターを取る形式
useQuery(options, paramsGetter) は削除されています。詳しくは
references/migration.md を参照してください。
クエリ状態の共有:defineQuery
複数のコンポーネントで使うクエリをラップすると、小さな Pinia ストアのように ref が一度だけ作成されます。セットアップ関数は同期処理である必要があります。
export const useFilteredTodos = defineQuery(() => {
const search = ref('')
const query = useQuery({
key: () => ['todos', { search: search.value }],
query: () => fetchTodos(search.value),
})
return { ...query, search }
})
ミューテーションと無効化
const queryCache = useQueryCache()
const { mutate, isLoading } = useMutation({
mutation: (text: string) => createTodo(text),
async onSettled() {
await queryCache.invalidateQueries({ key: ['todos'] })
},
})
mutate(vars)は決して reject しません。テンプレートやイベントハンドラーで使用します。mutateAsync(vars)は Promise を返し、失敗時には reject します。- 後続のフックで返されたコンテキストが推論されるよう、オプションオブジェクトでは
onMutateをmutationより前に記述します(dist/index.d.mts:1410-1433)。 - 楽観的更新:
onMutateでキャッシュを書き換え、キャッシュにまだ楽観的な値が残っている場合にのみonErrorでロールバックします。完全なパターンは references/mutations.md を参照してください。
クエリには onSuccess / onError がありません
これは意図的な仕様です。クエリには複数のウォッチャーが存在する場合があります。watch(data, ...) を使用するか、
PiniaColadaQueryHooksPlugin を介してグローバルフックを使用してください
(https://pinia-colada.esm.dev/plugins/official/query-hooks.md)。
バージョンに関する重要なルール(1.x)
useQuery(setup, paramsGetter)とuseQueryState(setup, paramsGetter)は 1.0.0 で削除されました。同梱の codemod を使って移行してください:ast-grep scan -r node_modules/@pinia/colada/codemods/rules/migration-0-21-to-1-0.yaml -i src(https://github.com/posva/pinia-colada/blob/main/CHANGELOG.md)。useQueryState(key)はフェッチせずにクエリの状態を読み取ります。引数はキーのみです (dist/index.d.mts:920-926)。initialDataはクエリの状態をsuccessに変更します。placeholderDataはキャッシュを 変更しません (dist/index.d.mts:558-600)。- エントリーの状態を手動でリセットするには、
queryCache.setEntryState(entry, state)を使います。setQueryData()でデータをundefinedに設定しても、状態はリセットされなくなりました。 - 無限クエリのデータは
{ pages, pageParams }です。無限クエリのエントリーを初期化するには、setQueryData()ではなくsetInfiniteQueryData()(1.2.0 で追加)を使います。 - Devtools は別のパッケージです:
@pinia/colada-devtools。 - Nuxt:
@pinia/colada-nuxtモジュールをインストールしてください。SSR のシリアライズは 自動的に処理されます。
参考資料
- queries.md:
useQueryAPI、オプション、戻り値、useQueryState、defineQuery、defineQueryOptions、キーのファクトリー - mutations.md:
useMutationAPI、フックと コンテキスト、楽観的更新、defineMutation、defineMutationOptions - infinite-queries.md:
useInfiniteQuery、defineInfiniteQueryOptions、setInfiniteQueryData、maxPages - query-cache.md:キャッシュストア、無効化、 フィルター、キャッシュへの手動書き込み、エラーコード
- plugins.md:プラグイン API、
PiniaColadaQueryHooksPlugin、TypesConfigの拡張、公式プラグインパッケージ - ssr.md:シリアライズとハイドレーション、遅延クエリ、
PiniaColadaSSRNoGc - migration.md:0.x から 1.x への変更と codemod