名称: pinia-colada 描述: Pinia Colada 为 Vue/Nuxt 提供数据获取功能,使用 useQuery、useMutation。用于异步状态、查询缓存、SSR,或遇到失效、水合、TanStack Vue Query 迁移错误。
关键词: Pinia Colada, @pinia/colada, useQuery, useMutation, useQueryCache, 数据获取, 异步状态, Vue 3, Nuxt, Pinia, 服务器状态, 缓存, staleTime, gcTime, 查询失效, 预取, 乐观更新, 突变, 查询键, 分页查询, SSR, 服务器端渲染, Nuxt 模块, @pinia/colada-nuxt, 查询缓存, 自动重新获取, 缓存失效, 请求去重, 加载状态, 错误处理, onSettled, onSuccess, onError, defineColadaLoader 许可证: MIT 元数据: 版本: “2.0.0” pinia_colada_version: “0.17.9” pinia_version: “3.0.4” vue_version: “3.5.25” 最后验证: “2025-11-28” 生产测试: true 令牌节省: “~65%” 错误预防: 12 包含参考: 4
Pinia Colada - Vue 的智能数据获取
状态: 生产就绪 ✅ | 最后更新: 2025-11-28 最新版本: @pinia/colada@0.17.9 | 依赖: Vue 3.5.17+, Pinia 2.2.6+ 或 3.0+
快速开始(5 分钟)
1. 安装依赖
对于 Vue 项目:
bun add @pinia/colada pinia # 首选
# 或: bun add @pinia/colada pinia
对于 Nuxt 项目:
bun add @pinia/nuxt @pinia/colada-nuxt # 安装 Pinia 和 Pinia Colada 模块
# 或: 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, {
// 可选: 配置默认值
query: {
staleTime: 5000, // 5 秒
gcTime: 5 * 60 * 1000, // 5 分钟 (垃圾回收)
refetchOnMount: true,
refetchOnWindowFocus: false,
},
})
app.mount('#app')
对于 Nuxt 项目:
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'@pinia/nuxt', // 必须在 @pinia/colada-nuxt 之前
'@pinia/colada-nuxt',
],
// 可选: 配置 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('获取待办事项失败')
}
return response.json()
}
const {
data, // Ref<Todo[] | undefined>
isPending, // Ref<boolean> - 初始加载
isLoading, // Ref<boolean> - 任何加载 (包括重新获取)
error, // Ref<Error | null>
refresh, // () => Promise<void> - 手动重新获取
} = useQuery({
key: ['todos'],
query: fetchTodos,
})
</script>
<template>
<div>
<div v-if="isPending">加载待办事项中...</div>
<div v-else-if="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('创建待办事项失败')
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,
// 突变成功后使待办事项查询失效
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 ? '添加中...' : '添加待办事项' }}
</button>
<div v-if="error">错误: {{ error.message }}</div>
</form>
</template>
为什么有效:
onSettled在成功或错误后运行,适合用于失效invalidateQueries将匹配查询标记为陈旧并重新获取活动查询mutate是触发即忘,mutateAsync返回 Promise 用于 await- 突变默认不缓存 (对于写入的正确行为)
关键规则
必须做
✅ 在键中包含查询函数中使用的所有变量
✅ 在查询/突变函数中抛出错误以正确处理错误
✅ 在突变中使用 useQueryCache() 进行失效
✅ 使用 isPending 表示初始加载,isLoading 表示任何加载状态
✅ 在需要数据新鲜时,在 onSettled 中等待 invalidateQueries()
✅ 对于分页查询使用 placeholderData 避免闪烁
✅ 在乐观更新前使用 getQueryData 快照缓存
✅ 从 onMutate 返回上下文以在 onError 中回滚
✅ 在插件级别配置 staleTime 和 gcTime 以获得应用范围的默认值
✅ 使用可复用的组合函数进行查询,而不是内联 useQuery
切勿做
❌ 切勿使用纯字符串作为键 - 始终使用数组
❌ 切勿从查询函数返回 undefined - 改为抛出错误
❌ 切勿直接突变 data.value - 它是只读的
❌ 切勿在突变后忘记使相关查询失效
❌ 切勿在查询中使用 onSuccess (不可用,使用 watch 代替)
❌ 切勿忘记等待 mutateAsync() - 它返回一个 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'] })
// 然后进行乐观更新
}
参见: references/error-catalog.md #2
错误 #3: SSR 水合不匹配
错误: Hydration completed but contains mismatches
预防: 对于 SSR 查询设置 refetchOnMount: false
useQuery({
key: ['todos'],
query: fetchTodos,
refetchOnMount: false, // 防止 SSR 水合不匹配
})
参见: references/error-catalog.md #3
错误 #4: 查询键非响应式
错误: 变量更改时查询未重新获取 预防: 使用函数作为响应式键:
// ❌ 错误 - 静态键
key: ['todos', id.value]
// ✅ 正确 - 响应式键
key: () => ['todos', id.value]
参见: references/error-catalog.md #4
错误 #5: Nuxt 模块顺序错误
错误: PiniaColada plugin not found 或 SSR 错误
预防: 始终将 @pinia/nuxt 放在第一位:
export default defineNuxtConfig({
modules: [
'@pinia/nuxt', // 必须首先
'@pinia/colada-nuxt', // 然后 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 差异
- 代码修改建议
- 破坏性更改
- 加载时机: 用户提到 TanStack Vue Query 或迁移
常见用例
- 基本待办事项列表与 CRUD - 查询 + 突变带失效 (10 分钟) → 参见
references/setup-guide.md步骤 2-4 - 分页数据表 - 响应式键带 placeholderData (15 分钟) → 参见
references/setup-guide.md步骤 7 - 乐观 UI 更新 - 突变带 onMutate/onError 回滚 (20 分钟) → 参见
references/setup-guide.md步骤 5 - Nuxt SSR 应用 - 自动导入带 refetchOnMount 配置 (15 分钟) → 参见
references/setup-guide.md步骤 8 - 实时仪表板 - 后台轮询带 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
- 用户询问 “与…有什么不同”
依赖
必需:
- @pinia/colada@0.17.9 - 核心数据获取层
- pinia@2.2.6+ 或 pinia@3.0+ - 状态管理 (对等依赖)
- vue@3.5.17+ - 框架 (对等依赖)
可选:
- @pinia/colada-nuxt@0.17.9 - Nuxt 模块 (需要单独安装 @pinia/nuxt)
官方文档
- Pinia Colada: https://pinia-colada.esm.dev/
- GitHub 仓库: https://github.com/posva/pinia-colada
- Pinia: https://pinia.vuejs.org/
- Nuxt 模块: https://nuxt.com/modules/pinia-colada
- 迁移指南: https://pinia-colada.esm.dev/cookbook/migration-tvq.html
包版本 (已验证 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 应用的生产使用:
- 令牌节省: ~65% 对比手动 TanStack Query 设置
- 错误预防: 上面记录的 12 个常见问题
- 构建时间: < 2 分钟用于基本设置
- 验证: ✅ SSR 工作, ✅ TypeScript 类型正确, ✅ Nuxt 中自动导入工作
完整设置检查清单
使用此检查清单验证您的设置:
- [ ] 已安装
@pinia/colada和pinia(或对于 Nuxt@pinia/colada-nuxt) - [ ] 在
createPinia()(Vue) 后注册了PiniaColada插件或添加到模块 (Nuxt) - [ ] 创建了至少一个查询使用
useQuery - [ ] 创建了至少一个突变使用
useMutation - [ ] 在突变
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 个常见问题都记录并预防。