如果你的 Vue 项目里还有这样的代码片段,或许该考虑换一种更优雅的方式了。
const data = ref(null)
const isLoading = ref(false)
const error = ref(null)
const fetchData = async () => {
isLoading.value = true
try {
const res = await api.getUser()
data.value = res
} catch (err) {
error.value = err
} finally {
isLoading.value = false
}
}
手动管理 data、isLoading、error 这些状态,在异步逻辑复杂的应用中很快就会变成“样板代码地狱”。今天要介绍的,是来自 Vue.js 核心团队成员、Pinia 作者 Eduardo 的新作—— Pinia Colada。

什么是 Pinia Colada?
简单来说, Pinia Colada = Pinia + 异步数据管理。
它并非一个简单的 HTTP 客户端替代品,而是一个构建在 Pinia 之上的、专为 Vue.js 设计的异步状态管理层。它深度集成于 Vue 的响应式系统,体积轻巧(gzip 后不到 2KB),旨在彻底简化数据获取、缓存和状态同步的复杂度。
官方将其描述为“为 Vue 量身定制的智能数据获取层”。

为什么要选择 Pinia Colada?
1. 告别样板代码
无需再手动声明和管理 isLoading、isError、data、error 等一系列状态变量。Pinia Colada 的核心 useQuery 组合式函数,让你一行代码就能搞定异步状态。
// 逻辑高度内聚,状态自动管理
const { data, status, error } = useQuery({
key: ['user-list'], // 请求的唯一标识
query: () => fetch('/api/users'), // 你的异步函数
})
// status 自动管理 'pending' | 'success' | 'error' 三种状态
// 你只需关心数据本身
2. 开箱即用的缓存与请求去重
这是最实用的特性之一。想象一个场景:页面中多个独立组件都需要同一份“用户信息”数据。
- 传统做法:要么每个组件各自发起请求造成浪费,要么通过提升状态到父组件再层层传递(Prop Drilling),增加了耦合度。
- Pinia Colada 做法:在任何组件中调用相同
key 的 useQuery,库会自动识别并只发起一次网络请求,然后将结果共享给所有订阅者。
这既节省了网络资源,又让组件逻辑保持独立和清晰。
3. 原生于 Pinia 的开发者体验
市面上其他类似库(如 Vue Query)功能强大,但其内部状态对于开发者来说可能像个“黑盒”,调试时不够直观。
Pinia Colada 不同,它直接利用 Pinia Store 来存储所有异步状态和数据。这意味着你可以直接打开 Vue DevTools,像查看普通响应式状态一样,清晰地审查每一个请求的缓存、状态、错误信息和数据结构,调试体验无缝衔接。
实战对比:重构一个 Pinia Store
假设我们要在 Store 中实现一个获取“联系人列表”的功能,对比一下传统写法和使用 Pinia Colada 的差异。
传统 Pinia Store 写法:
import { defineStore } from 'pinia'
import { ref, shallowRef } from 'vue'
import { api } from './api' // 你的请求封装
export const useContactListStore = defineStore('contact-list', () => {
// 1. 定义数据
const contacts = shallowRef([])
// 2. 定义一堆状态变量
const status = ref('idle') // 'idle' | 'loading' | 'success' | 'error'
const error = shallowRef(null)
// 3. 手动编写获取逻辑
async function fetchContacts() {
// 每次请求前,重置状态
status.value = 'loading'
error.value = null
try {
const res = await api.getContacts()
contacts.value = res
status.value = 'success'
} catch (err) {
error.value = err
status.value = 'error'
}
}
return {
contacts,
status,
error,
fetchContacts,
}
})
基于 Pinia Colada 的写法:
import { defineStore } from 'pinia'
import { useQuery } from '@pinia/colada'
import { api } from './api'
export const useContactListStore = defineStore('contact-list', () => {
// 一切状态由 useQuery 自动管理
const {
data: contacts, // 自动将结果赋值给 contacts
status, // 自动管理 'pending' | 'success' | 'error'
error, // 自动捕获错误
asyncStatus // 更详细的异步状态
} = useQuery({
key: ['contacts'], // 唯一标识,实现自动去重和缓存
query: () => api.getContacts(),
})
return { contacts, status, error, asyncStatus }
})
差异显而易见:
- 无需 try-catch:错误被自动捕获并赋值给
error。
- 无需手动切换 loading 状态:
status 值自动更新。
- 自带请求去重与缓存:多个组件使用此 Store 只会触发一次请求;页面切换时,后台刷新等策略也可轻松配置。
Pinia Colada 现在可以投入生产吗?
需要冷静看待的是,Pinia Colada 目前仍处于 Alpha/Beta 阶段(版本号为 0.x)。

其 API 设计借鉴了成熟的 TanStack Query,但未来仍可能发生较大变更。
因此,建议如下:
- 个人项目/实验性项目:可以大胆采用,其开发体验的提升是立竿见影的。
- 企业核心生产项目:建议保持关注,或在诸如后台管理系统等非核心、迭代快速的模块中小范围试用,评估其稳定性和对团队工作流的提升效果。
对于新兴的 前端 工具,保持好奇与实践,并在合适的场景引入,是推动项目与个人技术栈持续优化的关键。如果你在评估或使用中遇到了有趣的问题,欢迎在云栈社区与其他开发者交流心得。