作为一个深耕 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/