关于 tanstack-vue-store-skilld
tanstack-vue-store-skilld 是使用 @tanstack/vue-store 的技能参考;该库为 TanStack Store 提供 Vue 适配。它面向 Vue 开发者,提供选择器和 atom 钩子连接组件响应式状态,并从同一包重新导出核心 API。
主要功能
- 01用 useSelector 读取 Store 或 atom
- 02用 useAtom 读写 atom
- 03通过 _useStore 访问 Store 操作
- 04重新导出 TanStack Store 核心 API
- 05经 vue-demi 支持 Vue 2 和 Vue 3
适用场景
- 01让组件订阅选定的 Store 状态片段
- 02在 Vue 组件间共享模块级 Store
- 03将多次状态更新合并为一次通知
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ skilld-dev/ vue-ecosystem-skills --skill tanstack-vue-store-skilld安装后在 Claude Code 中输入/tanstack-vue-store-skilld确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/core-api.mdmigration.mdpatterns.mdvue-hooks.md详细介绍
@tanstack/[email protected]
TanStack Store 的 Vue 适配器。精确的核心依赖:@tanstack/[email protected](package.json:41)。src/index.ts:1 重新导出整个核心,因此 Vue 应用只需从 @tanstack/vue-store 导入所有内容。
快速开始
import { createStore, createAtom, shallow, useAtom, useSelector } from '@tanstack/vue-store'
// Module scope: create once, import anywhere
const counter = createStore({ count: 0 })
const countAtom = createAtom(0)
// Inside <script setup>
const count = useSelector(counter, (s) => s.count) // slice
const pair = useSelector(counter, (s) => ({ n: s.count }), { compare: shallow }) // object slice
const [n, setN] = useAtom(countAtom) // read + write
setN((prev) => prev + 1)
在模板中将 ref 读取为 {{ count }},在脚本中读取为 count.value。
Hooks(本包自身导出的内容)
| Hook | 签名 | 用途 |
|---|---|---|
useSelector | (source, selector?, options?) => Readonly<Ref<TSelected>> | 主要的读取 Hook。支持 Store、atom,或任何 { get, subscribe } 来源。省略 selector 即可订阅整个值。 |
useAtom | (atom, options?) => [Readonly<Ref<TValue>>, atom.set] | 读取并写入一个可写 atom。setter 接受一个值或 updater 函数(src/useAtom.ts:20-27)。 |
_useStore | (store, selector, options?) => [selected, actions or setState] | 实验性的读写元组。必须提供 selector 参数(src/_useStore.ts:30)。如果 Store 有 actions 工厂,则返回 store.actions,否则返回 store.setState(src/_useStore.ts:37-38)。 |
useStore | 已弃用 | useSelector 的别名。第三个参数是裸 compare 函数,而不是选项对象(src/useStore.ts:14-23)。建议使用 useSelector。 |
options 的类型为 UseSelectorOptions:{ compare?: (a, b) => boolean }(src/useSelector.ts:4-6)。
详情、行为说明和注意事项:Vue Hooks 参考
避免错误的规则
- 默认比较方式为严格的
===(src/useSelector.ts:15-17)。当 selector 创建新的对象或数组时,传入{ compare: shallow },否则每次收到通知都会更新 ref。原始值 selector 无需自定义比较方式。 - 在组件的 setup 或其他 effect scope 内调用这些 Hooks。
useSelector通过onScopeDispose取消订阅(src/useSelector.ts:54-56);在作用域外调用时,永远不会执行清理。 - 返回的 ref 是
readonly。通过store.setState、atom.set、Storeactions,或useAtom/_useStore的第二个元组元素进行写入。 - 保持 selector 开销低。每次来源收到通知时都会运行 selector(
src/useSelector.ts:46-52);将耗时计算移到派生的createStore中。 - 不要从本包导入
createStoreContext。0.11.0 版本说明中列出了它,但 0.11.1 源码只导出useSelector、useAtom、useStore、_useStore,以及核心重新导出内容(src/index.ts、dist/index.d.ts)。参见版本 0.11.0。
从 @tanstack/store 重新导出的核心内容
createStore(initialValue)->Store<T>;createStore((prev?) => T)->ReadonlyStore<T>(派生);createStore(initialValue, actionsFactory)->Store<T, TActions>,其中store.actions带有类型。Store:stategetter、get()、setState(updater)、subscribe(observerOrFn)(返回{ unsubscribe })、绑定的actions。ReadonlyStore不包含setState和actions。createAtom(initialValue)-> 可写的Atom<T>;createAtom(fn)-> 计算得到的ReadonlyAtom<T>。AtomOptions.compare用于控制变更检测。createAsyncAtom(() => Promise<T>)-> 一个ReadonlyAtom,其值为{ status }判别联合类型:'pending' | 'done' | 'error'。batch(fn)将多次更新合并为一个通知周期;flush()清空待处理的 effects。shallow(a, b)会比较Object.is,然后比较 Map 和 Set 内容、Date 时间戳,以及包括符号键在内的自有键。toObserver()将回调或 RxJS 风格的 observer 规范化,以供subscribe使用。- 类型:
Observer、Subscription、Subscribable、Readable、Atom、ReadonlyAtom、AtomOptions、StoreActionMap、StoreActionsFactory等。
完整 API 及注意事项:核心 API 参考
最佳实践
- 新代码使用
useSelector,绝不使用已弃用的useStore(src/useSelector.ts:39)。 - 在组件外的普通模块中定义存储。这是文档推荐的共享模式(Vue 快速入门)。
- 选择细粒度的状态切片。只有选中的值发生变化时,组件才会重新渲染。
- 使用
store.setState((prev) => next)更新函数写入状态;更新是不可变的。 - 将多个更新放入
batch(() => { ... }),这样订阅者只会收到一次通知,且获得最终状态。 - 使用
createStore(() => ...)派生状态;依赖项变化时,派生存储会重新计算,且prev会累积值。 - 将写入操作与 actions 工厂放在一起,以便
_useStore返回类型化的 actions(src/_useStore.ts:37-38)。 - 异步数据使用
createAsyncAtom,而不是手动处理待处理和错误标记。 - 使用
store.subscribe(() => ...)在组件外观察状态;它会返回{ unsubscribe }。
配方和完整示例:模式参考
迁移
按版本列出的变更和升级步骤,按时间从近到远排列:迁移参考
要点:
- 0.11.x:引入
useSelector作为主要钩子;useStore已弃用;默认比较方式为===,取代 0.11 之前的shallow默认值和{ equal }选项。 - 0.9.0 破坏性变更:
new Store()->createStore();new Derived()-> 派生式createStore(fn);移除new Effect(),改用store.subscribe()。
环境
- Vue
^3.0.0或通过vue-demi使用^2.5.0。Vue 2 需要可选的对等依赖@vue/composition-api@^1.2.1(package.json:50-58)。 - 核心版本精确固定为
@tanstack/[email protected];核心 API 会重新导出,因此 Vue 应用无需单独安装核心包。 - 双格式:通过
import条件使用 ESM(dist/index.js),通过require使用 CJS(dist/index.cjs);类型定义位于dist/index.d.cts;sideEffects: false。 - 已测试 TypeScript 5.6 至 5.9(package.json:62-66)。
评论
支持 Markdown