mcpField
T
tanstack-vue-store-skilld

tanstack-vue-store-skilld

github.com/skilld-dev开发18498 次安装3 周前更新
代码仓库

关于 tanstack-vue-store-skilld

tanstack-vue-store-skilld 是使用 @tanstack/vue-store 的技能参考;该库为 TanStack Store 提供 Vue 适配。它面向 Vue 开发者,提供选择器和 atom 钩子连接组件响应式状态,并从同一包重新导出核心 API。

主要功能

  1. 01用 useSelector 读取 Store 或 atom
  2. 02用 useAtom 读写 atom
  3. 03通过 _useStore 访问 Store 操作
  4. 04重新导出 TanStack Store 核心 API
  5. 05经 vue-demi 支持 Vue 2 和 Vue 3

适用场景

  1. 01让组件订阅选定的 Store 状态片段
  2. 02在 Vue 组件间共享模块级 Store
  3. 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.md
migration.md
patterns.md
vue-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、Store actions,或 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:state getter、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