作为一个深耕 Vue 3 + Vite 的开发者,我为什么把"全家桶"全扔了?
曾经的我:
pinia管全局状态vue-router管路由element-plus的<el-table>管表格- 自己封装
useAxios管接口缓存
每新增一个需求,就要再学一套 API,再踩一堆坑。
直到某天,隔壁 React 同事甩给我一张截图:
TanStack Query DevTools 里,缓存、轮询、失效一屏看全;

我酸了------这不就是 Vue 梦寐以求的"数据层圣杯"吗?
更离谱的是,他轻描淡写一句:
"这玩意儿 Vue 也能用,官方包 @tanstack/vue-query 都出到 v5 了。"
于是,我试了一下午,结果------
我把 Pinia、el-table、手写缓存全部卸载了;
路由仍保留官方 vue-router@4,因为 TanStack Router 目前仅支持 React。
一个 TanStack(Query + Table + Form + Virtual),真·一个库组合,搞定 90 % 的痛点。
什么是 TanStack
TanStack 是一组「无头(Headless)+ 类型安全 + 跨框架」的微型库集合。

当前 Vue 生态可直接使用的成员:
| 场景 | 库名 | 一句话定位 |
|---|---|---|
| 数据/服务端状态 | @tanstack/vue-query |
请求、缓存、轮询、乐观更新一把梭 |
| 表格/数据网格 | @tanstack/vue-table |
万行数据 60 FPS,UI 100 % 自定义 |
| 表单 | @tanstack/vue-form |
类型安全的无头表单 |
| 虚拟滚动 | @tanstack/vue-virtual |
长列表一次性渲染不卡 |
注意:TanStack Router 尚未推出 Vue 版本 ,路由请继续使用官方
vue-router@4。
TanStack 优势
-
类型安全到牙齿
纯
TypeScript编写,自动补全 + 编译时校验。 -
真正的无头(Headless)
只给逻辑,不给
UI;样式、组件库随意换。 -
跨框架同构
Query/Table/Form/Virtual均已支持Vue、React、Solid、Svelte、Angular,学会一次,到处复用。

- 开发体验拉满
TanStack Query DevTools 一键调试缓存;统一ESLint/Vite插件。
如何快速上手 TanStack(Vue 3)
1. 安装核心包
bash
npm i @tanstack/vue-query @tanstack/vue-table
2. 启用插件
ts
// main.ts
import { createApp } from 'vue'
import { VueQueryPlugin } from '@tanstack/vue-query'
import App from './App.vue'
createApp(App).use(VueQueryPlugin).mount('#app')
3. 30 秒跑通「用户列表 + 搜索 + 分页」
html
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
import { useVueTable, flexRender, getCoreRowModel } from '@tanstack/vue-table'
const fetchUsers = async () => (await fetch('/api/users')).json()
const { data } = useQuery({ queryKey: ['users'], queryFn: fetchUsers })
const columns = [
{ accessorKey: 'id', header: 'ID' },
{ accessorKey: 'name', header: '姓名' },
{ accessorKey: 'email', header: '邮箱' }
]
const table = useVueTable({
get data() { return data.value ?? [] },
columns,
getCoreRowModel: getCoreRowModel()
})
</script>
<template>
<table class="w-full">
<thead>
<tr v-for="hg in table.getHeaderGroups()" :key="hg.id">
<th v-for="h in hg.headers" :key="h.id">
{{ flexRender(h.column.columnDef.header, h.getContext()) }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in table.getRowModel().rows" :key="row.id">
<td v-for="cell in row.getVisibleCells()" :key="cell.id">
{{ flexRender(cell.column.columnDef.cell, cell.getContext()) }}
</td>
</tr>
</tbody>
</table>
</template>
但 TanStack 的野心远不止 Vue
| 框架 | 已支持包 | 使用体验 |
|---|---|---|
| React | @tanstack/react-* |
hooks |
| Vue | @tanstack/vue-* |
Composition API |
| Solid | @tanstack/solid-* |
signals |
| Svelte | @tanstack/svelte-* |
stores |
| Angular | @tanstack/angular-* |
inject |
路由除外:目前仅 React 有
@tanstack/react-router,Vue 仍需vue-router@4。
迁移前后对比(真实 Vue 3 项目)
| 维度 | 迁移前 | 迁移后 |
|---|---|---|
| 状态管理 & 数据层 | Pinia + 手写缓存 | @tanstack/vue-query |
| 路由 | vue-router@4 |
保持不变(无 Vue 版 TanStack Router) |
| 表格 | element-plus <el-table> |
@tanstack/vue-table |
| 包体积(gzip) | 312 KB | 198 KB |
| 大表格 FPS | 45--55 | 60(虚拟滚动) |
| 代码行数 | 2,300 | 1,100 |
最后
TanStack 把「数据、表格、表单、虚拟滚动」这些最通用、最痛点的需求抽象成无头、跨框架、类型安全的微型库;
如果你也想丢掉 Pinia、el-table、手写缓存,却又不想被全家桶绑架------
现在就把 npm i @tanstack/vue-query @tanstack/vue-table 敲进终端,
一个库组合,搞定 90 % 的现代 Web 需求。
- TanStack 官网 :
https://tanstack.com/