mcpField
T
tanstack-vue-form-skilld

tanstack-vue-form-skilld

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

关于 tanstack-vue-form-skilld

面向 Vue 3 的类型安全表单状态库,提供字段、表单组和响应式状态选择能力。适合构建带验证及数组字段的表单。

主要功能

  1. 01类型安全的表单状态
  2. 02字段与表单组
  3. 03同步及异步验证
  4. 04响应式状态选择
  5. 05数组字段操作

适用场景

  1. 01构建 Vue 3 表单
  2. 02验证字段及表单数据
  3. 03管理动态数组字段

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/skilld-dev/vue-ecosystem-skills --skill tanstack-vue-form-skilld

安装后在 Claude Code 中输入/tanstack-vue-form-skilld确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api-surface.md
array-fields.md
form-groups.md
reactivity.md
validation.md

详细介绍

@tanstack/vue-form 1.33.5

为 Vue 3 提供无头、类型安全的表单状态管理。此包重新导出 @tanstack/form-core 的全部内容,并添加 Vue 组件和钩子(src/index.ts:1-5)。

环境

  • 研究版本:@tanstack/[email protected],打包了 @tanstack/[email protected] 和 @tanstack/vue-store@^0.11.0(package.json:39-42)。
  • 对等依赖:vue ^3.4.0(package.json:48-50)。测试矩阵涵盖 TypeScript 5.4 至 5.9(package.json:54-60)。
  • 仅从包根目录导入。唯一的子路径导出是 ./package.json(package.json:21-33)。同时支持 ESM/CJS,sideEffects: false。
  • 官方文档:https://tanstack.com/form/latest/docs/framework/vue/overview

最简表单

<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'

const form = useForm({
  defaultValues: {
    fullName: '',
  },
  onSubmit: async ({ value }) => {
    console.log(value)
  },
})
</script>

<template>
  <form @submit.prevent.stop="form.handleSubmit">
    <form.Field name="fullName">
      <template v-slot="{ field }">
        <input
          :name="field.name"
          :value="field.state.value"
          @blur="field.handleBlur"
          @input="(e) => field.handleChange((e.target as HTMLInputElement).value)"
        />
      </template>
    </form.Field>
    <button type="submit">Submit</button>
  </form>
</template>

来源:官方快速入门,https://tanstack.com/form/latest/docs/framework/vue/quick-start

字段绑定规则

  • 使用 form.Field 组件创建字段。name 属性必须是 defaultValues 的深层键,例如 'details.email' 或 `people[${i}].name`。
  • 作用域插槽接收 { field, state }(src/useField.tsx:543-547)。field 是一个 FieldApi,state 与 field.state 保持一致。
  • 输入框采用受控方式:绑定 :value="field.state.value",通过 field.handleChange 推送更新,并绑定 @blur="field.handleBlur"。
  • 对于数字输入框,使用 (e.target as HTMLInputElement).valueAsNumber。
  • 不要在插槽输入框上使用 v-model;状态通过 handleChange 流转。
  • form.Field 会在创建字段之前将其属性与透传属性合并(src/useField.tsx:541),因此可通过属性或透传属性传入验证器和监听器。

响应性

  • 在 <script setup> 中使用 form.useSelector((state) => state.values.firstName)。它返回 Readonly<Ref<T>>(src/useForm.tsx:155-189)。
  • form.useStore 已弃用;它与 useSelector 是同一个函数。请优先使用 form.useSelector(src/useForm.tsx:190-227, 336-337)。
  • 在模板中使用 <form.Subscribe>,可选传入 selector 属性。不设置 selector 时,插槽会接收整个表单状态(src/useForm.tsx:338-349)。
  • 不要直接调用 useField 钩子来实现响应性。它专为在 form.Field 内使用而设计;请改用 form.useSelector(官方基本概念说明,https://tanstack.com/form/latest/docs/framework/vue/guides/basic-concepts)。
  • useSelector 和 useStore 会从 @tanstack/vue-store 重新导出,用于直接访问原始 store(src/index.ts:2)。

详情:references/reactivity.md

验证要点

  • 通过 form.Field 上的 validators 属性或 useForm 选项中的 validators 传入验证器。钩子包括:onMount、onChange、onBlur、onSubmit、onDynamic,每种都提供对应的 Async 版本。
  • 验证器在验证通过时返回 undefined,否则返回任意类型的错误(通常是字符串)。错误会保存在 field.state.meta.errors 和 field.state.meta.errorMap 中。
  • Standard Schema 库可直接用作验证器:Zod v3.24.0 或更高版本、Valibot v1.0.0 或更高版本、ArkType v2.1.20 或更高版本、Yup v1.7.0 或更高版本(官方基本概念指南)。
  • 使用 async-debounce-ms 属性或每个验证器的 onChangeAsyncDebounceMs 对异步验证器进行防抖。
  • 只有在 useForm 选项中设置 validationLogic: revalidateLogic() 时,onDynamic 验证器才会运行。
<form.Field
  name="age"
  :validators="{
    onChange: z.number().gte(13, 'You must be 13 to make an account'),
  }"
>

详情:references/validation.md

数组字段

  • 为外层字段设置 mode="array"。在数组模式下,组件会跟踪 state.meta._arrayVersion 而不是值,因此子字段编辑不会导致整个列表重新渲染(src/useField.tsx:258-267, src/types.ts:12-15)。
  • 使用 v-for 遍历 field.state.value,并通过深层名称(如 `people[${i}].name`)渲染子字段。
  • 通过数组方法进行更改:pushValue、removeValue、swapValues、moveValue、insertValue、replaceValue、clearValues。

详情:references/array-fields.md

表单分组

  • <form.FormGroup name="step1" v-slot="{ group }"> 会为表单数据中的一个键构建子表单。插槽接收 { group, state }(src/useFormGroup.tsx:525-529)。
  • group.handleSubmit() 只提交并验证该分组;form.handleSubmit() 提交整个表单。
  • 分组验证器可以返回 { group, fields },其中 fields 的键相对于该分组;可以按步骤组合 Standard Schemas。

详情:references/form-groups.md

特定版本规则

  • 自 v1.28.0 起的重大变更:默认情况下,field.state.meta.errors 会被扁平化,因此是 ['err'],而不是 [['err']]。在字段选项中设置 disableErrorFlat: true,即可恢复旧的嵌套格式。发布说明:https://github.com/TanStack/form/releases/tag/%40tanstack%2Fvue-form%401.28.0
  • 已弃用:form.useStore,请改用 form.useSelector(src/useForm.tsx:190-192, 336-337)。
  • 已弃用:field.getValue(),请改为读取 field.state.value(官方 FieldApi 参考,https://tanstack.com/form/latest/docs/reference/classes/FieldApi)。
  • Field 接受 mode: 'value' | 'array'。数组模式用于避免列表重新渲染;参见 https://github.com/TanStack/form/issues/1925(src/useField.tsx:258-259)。
  • useForm 会在 Vue 的 useId 可用时据此生成适用于 SSR 的表单 ID,否则回退到 uuid,以确保服务端标记与客户端水合一致(src/useForm.tsx:272, src/useFormId.ts:18-24)。useFormId 本身是内部实现,并未导出(dist/esm/index.js)。
  • 可复用的选项集:从 form-core 导入 formOptions({ defaultValues }),并展开传入 useForm。

注意事项

  • Standard Schema 的转换不会保留。onSubmit 始终接收输入数据;如需转换后的输出,请在 onSubmit 内调用 schema.parse(value)(官方提交指南,https://tanstack.com/form/latest/docs/framework/vue/guides/submission-handling)。
  • 表单级验证器设置的字段错误可能会被该字段自己的验证器覆盖;在设置表单级字段错误后会运行字段验证(官方验证指南)。
  • 同步验证器会先运行;若同步验证失败,则会跳过对应的 Async 验证器,除非设置了 asyncAlways: true。
  • 在表单被触碰之前,canSubmit 为 true。若要在任何交互发生前禁用提交按钮,可组合使用 !canSubmit || isPristine。为保证无障碍性,优先使用 aria-disabled,而非 disabled(官方验证指南)。
  • Field 和 FormGroup 组件会自动传入父表单。只有单独导出的 Field 和 FormGroup 才需要显式设置 form 选项。
  • 异步默认值:使用 reactive 和 computed 引用包装(TanStack Query 模式,https://tanstack.com/form/latest/docs/framework/vue/guides/async-initial-values)。

参考资料

评论

支持 Markdown