pinia-colada-skilld

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

posva/pinia-colada
@pinia/colada

posva/pinia-colada
@pinia/colada

Version: 0.21.4 (Feb 2026) Tags: latest: 0.21.4 (Feb 2026)
References: Docs — API reference, guides • GitHub Issues — bugs, workarounds, edge cases • GitHub Discussions — Q&A, patterns, recipes • Releases — changelog, breaking changes, new APIs
版本:0.21.4(2026年2月) 标签:最新版:0.21.4(2026年2月)
参考文档:文档 — API参考、使用指南 • GitHub Issues — bug上报、解决方案、边缘场景处理 • GitHub Discussions — 问答、模式分享、实践方案 • 版本发布记录 — 更新日志、破坏性变更、新API

API Changes

API变更

This section documents version-specific API changes — prioritize recent major/minor releases.
  • BREAKING:
    useInfiniteQuery()
    — v0.20.0 refactored: removed
    merge
    , changed
    data
    to
    { pages, pageParams }
    ,
    initialPage
    initialPageParam
    ,
    loadMore
    loadNextPage
    , and
    getNextPageParam
    is now required (experimental) source
  • BREAKING:
    PiniaColada
    installation — v0.14.0 moved global options to
    queryOptions: { ... }
    and requires an options object for typing:
    app.use(PiniaColada, {})
    source
  • BREAKING:
    useQuery()
    aliases —
    isFetching
    was renamed to
    isLoading
    in v0.8.0 to better reflect its connection to
    asyncStatus
    source
  • BREAKING: Status split — v0.8.0 split
    status
    into
    status
    (data:
    'pending'|'success'|'error'
    ) and
    asyncStatus
    (operation:
    'idle'|'loading'
    ) source
  • BREAKING: Mutation IDs — v0.19.0 simplified mutation IDs to incremented numbers (starting at 1).
    mutationCache.get()
    now takes the ID, and
    $n
    suffix is removed from keys source
  • BREAKING: Cache Key structure — v0.16.0 refactored internal cache to support deeply nested objects for keys.
    toCacheKey
    now returns a plain string. Stricter types disallow
    undefined
    in keys source
  • BREAKING:
    queryCache
    method renames —
    cancelQuery()
    was renamed to
    cancel()
    in v0.11.0, and
    cancelQueries()
    was added for multiple cancellations source
  • BREAKING:
    setQueryState
    setEntryState
    — v0.9.0 renamed this
    queryCache
    action to better match its purpose source
  • BREAKING: External
    AbortError
    — v0.18.0 now surfaces external abort signals as actual errors instead of silently ignoring them source
  • BREAKING:
    placeholderData
    types — v0.13.0 changed
    placeholderData
    to only allow returning
    undefined
    (not
    null
    ) to improve type inference source
  • BREAKING: Devtools dependency — v0.21.0 removed built-in
    @vue/devtools-api
    dependency; use
    @pinia/colada-devtools
    instead source
  • NEW:
    useInfiniteQuery()
    — v0.13.5 introduced infinite scrolling support (experimental) source
  • NEW:
    useQueryState()
    — v0.17.0 added this for easier state management without the full
    useQuery
    return object source
  • NEW: Global Query Hooks — v0.8.0 introduced
    PiniaColadaQueryHooksPlugin
    to manage
    onSuccess
    ,
    onError
    , and
    onSettled
    source
Also changed:
serializeTreeMap
replaces
serialize
v0.14.0 ·
transformError
removed v0.12.0 ·
EntryKey
replaces
EntryNodeKey
v0.17.0 ·
TResult
renamed
TData
v0.16.0 ·
QueryPlugin
PiniaColada
v0.8.0 ·
delayLoadingRef
removed v0.12.0 ·
invalidateKeys
moved to plugin v0.10.0
本部分记录了特定版本的API变更——优先关注近期的主版本/次版本更新。
  • 重大变更:
    useInfiniteQuery()
    — v0.20.0版本重构:移除了
    merge
    ,将
    data
    改为
    { pages, pageParams }
    initialPage
    重命名为
    initialPageParam
    loadMore
    重命名为
    loadNextPage
    ,并且现在必须传入
    getNextPageParam
    (实验性特性)来源
  • 重大变更:
    PiniaColada
    安装方式
    — v0.14.0版本将全局选项移至
    queryOptions: { ... }
    中,并且要求传入一个选项对象以支持类型提示:
    app.use(PiniaColada, {})
    来源
  • 重大变更:
    useQuery()
    别名
    — v0.8.0版本将
    isFetching
    重命名为
    isLoading
    ,以更准确地反映其与
    asyncStatus
    的关联 来源
  • 重大变更:状态拆分 — v0.8.0版本将
    status
    拆分为
    status
    (数据状态:
    'pending'|'success'|'error'
    )和
    asyncStatus
    (操作状态:
    'idle'|'loading'
    来源
  • 重大变更:Mutation ID — v0.19.0版本简化了Mutation ID为递增数字(从1开始)。
    mutationCache.get()
    现在接收该ID,并且键名中的
    $n
    后缀已移除 来源
  • 重大变更:缓存键结构 — v0.16.0版本重构了内部缓存以支持键为深度嵌套对象。
    toCacheKey
    现在返回纯字符串。更严格的类型限制不允许键中出现
    undefined
    来源
  • 重大变更:
    queryCache
    方法重命名
    — v0.11.0版本将
    cancelQuery()
    重命名为
    cancel()
    ,并新增
    cancelQueries()
    用于取消多个请求 来源
  • 重大变更:
    setQueryState
    setEntryState
    — v0.9.0版本重命名了这个
    queryCache
    方法以更好地匹配其用途 来源
  • 重大变更:外部
    AbortError
    处理
    — v0.18.0版本现在将外部中止信号显示为实际错误,而不是静默忽略 来源
  • 重大变更:
    placeholderData
    类型
    — v0.13.0版本修改了
    placeholderData
    ,仅允许返回
    undefined
    (不允许
    null
    )以改进类型推断 来源
  • 重大变更:Devtools依赖 — v0.21.0版本移除了内置的
    @vue/devtools-api
    依赖;请改用
    @pinia/colada-devtools
    来源
  • 新增特性:
    useInfiniteQuery()
    — v0.13.5版本引入了无限滚动支持(实验性特性)来源
  • 新增特性:
    useQueryState()
    — v0.17.0版本新增了该API,无需完整的
    useQuery
    返回对象即可更轻松地管理状态 来源
  • 新增特性:全局查询钩子 — v0.8.0版本引入了
    PiniaColadaQueryHooksPlugin
    来管理
    onSuccess
    onError
    onSettled
    来源
其他变更:
serializeTreeMap
替代
serialize
(v0.14.0)·
transformError
被移除(v0.12.0)·
EntryKey
替代
EntryNodeKey
(v0.17.0)·
TResult
重命名为
TData
(v0.16.0)·
QueryPlugin
PiniaColada
(v0.8.0)·
delayLoadingRef
被移除(v0.12.0)·
invalidateKeys
移至插件中(v0.10.0)

Best Practices

最佳实践

  • Use the grouped
    state
    object for type-safe narrowing in templates — TypeScript cannot narrow destructured
    data
    or
    error
    refs based on the
    status
    ref due to Vue's
    Ref
    wrapper limitations source
vue
<script setup lang="ts">
const { state } = useQuery({ key: ['user'], query: fetchUser })
</script>

<template>
  <div v-if="state.status === 'success'">{{ state.data.name }}</div>
  <div v-else-if="state.status === 'error'">{{ state.error.message }}</div>
</template>
  • Wrap shared reactive state in
    defineQuery()
    to prevent desynchronization — regular composables recreate refs for each component instance, causing only the first component to successfully trigger key-based reactivity source
ts
export const useFilteredTodos = defineQuery(() => {
  const search = ref('')
  const query = useQuery({
    key: () => ['todos', { search: search.value }],
    query: () => fetchTodos(search.value),
  })
  return { ...query, search }
})
  • Combine hierarchical key factories with
    defineQueryOptions()
    for strict type safety — this enables automatic type inference in
    queryCache
    methods without manual type casting or string-based key typos source
ts
export const todoOptions = defineQueryOptions((id: string) => ({
  key: ['todos', id],
  query: () => fetchTodo(id),
}))
// Inferred TData: queryCache.getQueryData(todoOptions('1').key)
  • Handle side effects via
    watch
    or global plugins instead of query options —
    useQuery
    intentionally lacks
    onSuccess
    /
    onError
    to prevent side-effect duplication across multiple component instances source
  • Prefer
    refresh()
    over
    refetch()
    for standard UI updates —
    refresh()
    respects
    staleTime
    and deduplicates in-flight requests, whereas
    refetch()
    forces a network call regardless of cache status source
  • Use the
    meta
    property for declarative cross-cutting concerns — attach metadata to queries to drive global UI behavior (like toast messages) within the
    PiniaColadaQueryHooksPlugin
    source
  • Verify cache state before performing optimistic rollbacks — always check if the current cache value matches the optimistic value in
    onError
    to avoid overwriting concurrent successful updates from other mutations source
ts
onError(err, vars, { newTodo, oldTodo }) {
  if (newTodo === queryCache.getQueryData(['todos'])) {
    queryCache.setQueryData(['todos'], oldTodo)
  }
}
  • Use
    queryCache.setEntryState()
    for manual status synchronization — this is the preferred way to manually update an entry as setting data to
    undefined
    via
    setQueryData()
    is no longer supported for state resets source
  • Explicitly import
    useRoute
    from
    vue-router
    in Nuxt
    defineQuery
    definitions — the Nuxt auto-imported version can cause unnecessary query triggers or
    undefined
    values due to Suspense integration source
  • Use the
    enabled
    getter to guard "immortal" queries in global stores — prevents queries inside Pinia stores from making invalid network requests when required reactive parameters (like route params) are absent source
ts
const result = useQuery({
  key: () => ['deck', route.params.id],
  query: () => fetchDeck(route.params.id),
  enabled: () => !!route.params.id,
})
  • 在模板中使用分组的
    state
    对象实现类型安全的分支判断——由于Vue的
    Ref
    包装器限制,TypeScript无法根据
    status
    ref对解构后的
    data
    error
    ref进行类型收窄 来源
vue
<script setup lang="ts">
const { state } = useQuery({ key: ['user'], query: fetchUser })
</script>

<template>
  <div v-if="state.status === 'success'">{{ state.data.name }}</div>
  <div v-else-if="state.status === 'error'">{{ state.error.message }}</div>
</template>
  • 将共享响应式状态包装在
    defineQuery()
    中以防止不同步——常规的组合式函数会为每个组件实例重新创建ref,导致只有第一个组件能成功触发基于键的响应式更新 来源
ts
export const useFilteredTodos = defineQuery(() => {
  const search = ref('')
  const query = useQuery({
    key: () => ['todos', { search: search.value }],
    query: () => fetchTodos(search.value),
  })
  return { ...query, search }
})
  • 将分层键工厂与
    defineQueryOptions()
    结合使用以实现严格的类型安全——这能在
    queryCache
    方法中实现自动类型推断,无需手动类型转换或避免基于字符串的键名拼写错误 来源
ts
export const todoOptions = defineQueryOptions((id: string) => ({
  key: ['todos', id],
  query: () => fetchTodo(id),
}))
// 自动推断TData: queryCache.getQueryData(todoOptions('1').key)
  • 通过
    watch
    或全局插件处理副作用,而不是通过查询选项——
    useQuery
    刻意不提供
    onSuccess
    /
    onError
    ,以防止副作用在多个组件实例中重复执行 来源
  • 对于标准UI更新,优先使用
    refresh()
    而不是
    refetch()
    ——
    refresh()
    会尊重
    staleTime
    并对正在进行的请求进行去重,而
    refetch()
    会强制发起网络请求,无论缓存状态如何 来源
  • 使用
    meta
    属性声明式处理横切关注点——为查询附加元数据,以便在
    PiniaColadaQueryHooksPlugin
    中驱动全局UI行为(如提示消息)来源
  • 在执行乐观回滚前验证缓存状态——务必在
    onError
    中检查当前缓存值是否与乐观更新值匹配,以避免覆盖其他变更发起的并发成功更新 来源
ts
onError(err, vars, { newTodo, oldTodo }) {
  if (newTodo === queryCache.getQueryData(['todos'])) {
    queryCache.setQueryData(['todos'], oldTodo)
  }
}
  • 使用
    queryCache.setEntryState()
    进行手动状态同步——这是手动更新条目的推荐方式,因为通过
    setQueryData()
    将数据设置为
    undefined
    不再支持状态重置 来源
  • 在Nuxt的
    defineQuery
    定义中显式从
    vue-router
    导入
    useRoute
    ——Nuxt的自动导入版本可能会因Suspense集成导致不必要的查询触发或
    undefined
    来源
  • 在全局Store中使用
    enabled
    getter保护“永久”查询——当所需的响应式参数(如路由参数)不存在时,防止Pinia Store中的查询发起无效网络请求 来源
ts
const result = useQuery({
  key: () => ['deck', route.params.id],
  query: () => fetchDeck(route.params.id),
  enabled: () => !!route.params.id,
})