PiniaColada数据获取技能 pinia-colada

Pinia Colada 是一个用于 Vue 和 Nuxt 的智能数据获取库,提供 useQuery 和 useMutation 等功能,用于处理异步状态、查询缓存、服务器端渲染(SSR)、查询失效、乐观更新等。关键词:Pinia Colada, Vue, Nuxt, 数据获取, 缓存, SSR, 异步状态管理, useQuery, useMutation。

前端开发 0 次安装 0 次浏览 更新于 3/7/2026

名称: 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 仅在初始加载时为 trueisLoading 包括重新获取

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 中回滚 ✅ 在插件级别配置 staleTimegcTime 以获得应用范围的默认值 ✅ 使用可复用的组合函数进行查询,而不是内联 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 或迁移

常见用例

  1. 基本待办事项列表与 CRUD - 查询 + 突变带失效 (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.mdreferences/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)

官方文档


包版本 (已验证 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/coladapinia (或对于 Nuxt @pinia/colada-nuxt)
  • [ ] 在 createPinia() (Vue) 后注册了 PiniaColada 插件或添加到模块 (Nuxt)
  • [ ] 创建了至少一个查询使用 useQuery
  • [ ] 创建了至少一个突变使用 useMutation
  • [ ] 在突变 onSettled 钩子中使用了 invalidateQueries
  • [ ] 查询键是数组 (或返回数组的函数)
  • [ ] 所有查询变量包含在查询键中
  • [ ] 在查询/突变函数中抛出错误 (而不是返回)
  • [ ] 使用 isPending 表示初始加载状态
  • [ ] 为所有数据结构定义了 TypeScript 类型
  • [ ] 在插件级别配置了 staleTimegcTime (可选)
  • [ ] 开发环境运行无错误
  • [ ] 如果使用 Nuxt, SSR 工作 (检查水合)

问题? 错误? 检查: 官方文档 | references/setup-guide.md (8 步过程) | references/error-catalog.md (所有 12 个错误) | references/migration-from-tanstack-vue-query.md (迁移) | GitHub


此技能提供生产就绪的 Pinia Colada 设置,零配置错误。所有 12 个常见问题都记录并预防。