tanstack-vue-form-skilld

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TanStack/form
@tanstack/vue-form

TanStack/form
@tanstack/vue-form

Version: 1.28.3 (Feb 2026) Deps: @tanstack/vue-store@^0.8.1, @tanstack/form-core@1.28.3 Tags: latest: 1.28.3 (Feb 2026)
References: Docs — API reference, guides • GitHub Issues — bugs, workarounds, edge cases • GitHub Discussions — Q&A, patterns, recipes • Releases — changelog, breaking changes, new APIs
**版本:**1.28.3(2026年2月) 依赖:@tanstack/vue-store@^0.8.1,@tanstack/form-core@1.28.3 **标签:**latest: 1.28.3(2026年2月)
参考链接:文档 — API参考、使用指南 • GitHub Issues — bug反馈、解决方案、边缘场景处理 • GitHub Discussions — 问答、模式参考、实践方案 • 版本发布记录 — 更新日志、破坏性变更、新API介绍

API Changes

API变更

This section documents version-specific API changes for
@tanstack/vue-form
.
  • BREAKING:
    field.errors
    — v1.28.0 flattens errors by default (
    [error]
    not
    [[error]]
    ), use
    disableErrorFlat: true
    to restore old nested behavior source
  • DEPRECATED:
    field.getValue()
    — use
    field.state.value
    instead as direct accessor methods on FieldApi are deprecated in favor of state access source
  • NEW:
    field.parseValueWithSchema()
    — validates field value against Standard Schema V1 without affecting internal field error state source
  • NEW:
    form.parseValuesWithSchema()
    — form-level Standard Schema V1 validation helper for third-party schemas like Zod or Valibot source
  • NEW:
    formOptions()
    — helper to define reusable, type-safe form options with inference outside of the
    useForm
    hook source
  • NEW:
    Field
    component — declarative Vue component alternative to
    useField
    for defining form fields directly in templates source
  • NEW:
    Subscribe
    component — Vue component for fine-grained subscriptions to form or field state changes to optimize re-renders source
  • NEW:
    useStore()
    — Vue hook providing direct, reactive access to the underlying TanStack Store state for the form or field source
  • NEW:
    resetField()
    FormApi
    method to reset a specific field's value and metadata back to its default state source
  • NEW:
    clearFieldValues()
    FormApi
    utility to efficiently remove all items from an array field's data source
  • NEW:
    setErrorMap()
    — allows manual overriding of the internal validation error map for custom validation logic source
  • NEW:
    StandardSchemaV1
    — native support for the Standard Schema validation protocol across all validator fields source
  • NEW:
    mode
    option —
    UseFieldOptions
    now supports explicit
    'value'
    or
    'array'
    modes for better type safety in complex forms
  • NEW:
    disableErrorFlat
    — new option in
    FieldApiOptions
    to opt-out of automatic error flattening introduced in v1.28.0 source
Also changed:
resetFieldMeta()
new helper ·
insertFieldValue()
array utility ·
moveFieldValues()
array utility ·
swapFieldValues()
array utility ·
FieldApi.getInfo()
metadata helper ·
VueFieldApi
interface stabilization ·
VueFormApi
interface stabilization
本节记录
@tanstack/vue-form
各版本的API变更。
  • 破坏性变更:
    field.errors
    — v1.28.0版本默认将错误信息扁平化(变为
    [error]
    而非
    [[error]]
    ),可设置
    disableErrorFlat: true
    恢复旧的嵌套格式 来源
  • 已废弃:
    field.getValue()
    — 请改用
    field.state.value
    ,因为FieldApi上的直接访问方法已被废弃,推荐使用状态访问方式 来源
  • 新增:
    field.parseValueWithSchema()
    — 依据Standard Schema V1验证字段值,且不会影响字段内部的错误状态 来源
  • 新增:
    form.parseValuesWithSchema()
    — 表单级别的Standard Schema V1验证工具,支持Zod或Valibot等第三方校验库 来源
  • 新增:
    formOptions()
    — 用于在
    useForm
    钩子外部定义可复用、类型安全的表单选项,并支持类型推断的工具函数 来源
  • 新增:
    Field
    组件 — 声明式Vue组件,可替代
    useField
    ,用于在模板中直接定义表单项 来源
  • 新增:
    Subscribe
    组件 — Vue组件,用于对表单或字段的状态变更进行细粒度订阅,以优化重渲染性能 来源
  • 新增:
    useStore()
    — Vue钩子,提供对表单或字段底层TanStack Store状态的直接响应式访问 来源
  • 新增:
    resetField()
    FormApi
    方法,用于将指定字段的值和元数据重置回默认状态 来源
  • 新增:
    clearFieldValues()
    FormApi
    工具函数,用于高效清空数组字段中的所有数据项 来源
  • 新增:
    setErrorMap()
    — 允许手动覆盖内部校验错误映射,以实现自定义校验逻辑 来源
  • 新增:
    StandardSchemaV1
    — 所有校验字段原生支持Standard Schema校验协议 来源
  • 新增:
    mode
    选项 —
    UseFieldOptions
    现在支持显式的
    'value'
    'array'
    模式,以提升复杂表单的类型安全性
  • 新增:
    disableErrorFlat
    FieldApiOptions
    中的新选项,用于选择退出v1.28.0版本引入的自动错误扁平化功能 来源
**其他变更:**新增
resetFieldMeta()
工具函数 · 新增
insertFieldValue()
数组工具 · 新增
moveFieldValues()
数组工具 · 新增
swapFieldValues()
数组工具 ·
FieldApi.getInfo()
元数据工具优化 ·
VueFieldApi
接口稳定化 ·
VueFormApi
接口稳定化

Best Practices

最佳实践

  • Use
    formOptions()
    to define type-safe, reusable form configurations that can be shared across components or used for better type inference source
ts
const options = formOptions({
  defaultValues: { email: '' },
  validators: {
    onChange: z.object({ email: z.string().email() })
  }
})

const form = useForm(options)
  • Link field validations with
    onChangeListenTo
    to trigger re-validation when dependent field values change, such as password confirmations source
vue
<form.Field
  name="confirm_password"
  :validators="{
    onChangeListenTo: ['password'],
    onChange: ({ value, fieldApi }) =>
      value !== fieldApi.form.getFieldValue('password') ? 'Passwords do not match' : undefined
  }"
>
  • Implement
    async-debounce-ms
    at the field or validator level to throttle expensive asynchronous validation calls like API checks source
vue
<form.Field
  name="username"
  :async-debounce-ms="500"
  :validators="{
    onChangeAsync: async ({ value }) => checkUsername(value)
  }"
>
  • Parse Standard Schemas manually within
    onSubmit
    to retrieve transformed values, as the form state preserves the raw input data source
ts
const form = useForm({
  onSubmit: ({ value }) => {
    // schema.parse converts string to number if transform is defined
    const validatedData = loginSchema.parse(value)
    api.submit(validatedData)
  }
})
  • Pass custom metadata via
    onSubmitMeta
    to differentiate between multiple submission actions within a single
    onSubmit
    handler source
vue
<button @click="form.handleSubmit({ action: 'save_draft' })">Save Draft</button>
<button @click="form.handleSubmit({ action: 'publish' })">Publish</button>
  • Combine
    canSubmit
    with
    isPristine
    to ensure the submit button remains disabled until the user has actually interacted with the form source
vue
<template v-slot="{ canSubmit, isPristine }">
  <button :disabled="!canSubmit || isPristine">Submit</button>
</template>
  • Use
    form.useStore
    with a selector in
    <script setup>
    for granular, reactive access to form state without re-rendering on unrelated changes source
ts
const canSubmit = form.useStore((state) => state.canSubmit)
  • Enable
    asyncAlways: true
    when you need asynchronous validators to execute regardless of whether synchronous validation has already failed source
ts
// Runs async validation even if local regex check fails
const validators = {
  onChange: ({ value }) => !value.includes('@') ? 'Invalid' : undefined,
  onChangeAsync: async ({ value }) => api.check(value),
  asyncAlways: true
}
  • Return a
    fields
    mapping from form-level validators to update errors across multiple fields simultaneously from a single validation logic source
ts
validators: {
  onChange: ({ value }) => ({
    fields: {
      startDate: value.startDate > value.endDate ? 'Must be before end' : undefined,
      endDate: value.startDate > value.endDate ? 'Must be after start' : undefined
    }
  })
}
  • Use reactive objects for
    defaultValues
    when binding the form to dynamic or asynchronous data sources like TanStack Query source
ts
const { data } = useQuery(...)
const defaultValues = reactive({
  name: computed(() => data.value?.name ?? '')
})
const form = useForm({ defaultValues })
  • 使用
    formOptions()
    定义类型安全、可复用的表单配置,这些配置可在组件间共享,或用于优化类型推断 来源
ts
const options = formOptions({
  defaultValues: { email: '' },
  validators: {
    onChange: z.object({ email: z.string().email() })
  }
})

const form = useForm(options)
  • 使用
    onChangeListenTo
    关联字段校验,当关联字段值变化时触发重新校验,例如密码确认场景 来源
vue
<form.Field
  name="confirm_password"
  :validators="{
    onChangeListenTo: ['password'],
    onChange: ({ value, fieldApi }) =>
      value !== fieldApi.form.getFieldValue('password') ? 'Passwords do not match' : undefined
  }"
>
  • 在字段或校验器级别设置
    async-debounce-ms
    ,以节流耗时的异步校验调用(如API检查) 来源
vue
<form.Field
  name="username"
  :async-debounce-ms="500"
  :validators="{
    onChangeAsync: async ({ value }) => checkUsername(value)
  }"
>
  • onSubmit
    中手动解析Standard Schemas以获取转换后的值,因为表单状态会保留原始输入数据 来源
ts
const form = useForm({
  onSubmit: ({ value }) => {
    // schema.parse会根据转换规则将字符串转为数字
    const validatedData = loginSchema.parse(value)
    api.submit(validatedData)
  }
})
  • 通过
    onSubmitMeta
    传递自定义元数据,以便在单个
    onSubmit
    处理函数中区分不同的提交操作 来源
vue
<button @click="form.handleSubmit({ action: 'save_draft' })">保存草稿</button>
<button @click="form.handleSubmit({ action: 'publish' })">发布</button>
  • 结合
    canSubmit
    isPristine
    ,确保提交按钮在用户未与表单交互时保持禁用状态 来源
vue
<template v-slot="{ canSubmit, isPristine }">
  <button :disabled="!canSubmit || isPristine">提交</button>
</template>
  • <script setup>
    中结合选择器使用
    form.useStore
    ,以实现对表单状态的细粒度响应式访问,避免无关变更导致的重渲染 来源
ts
const canSubmit = form.useStore((state) => state.canSubmit)
  • 当需要无论同步校验是否失败都执行异步校验时,启用
    asyncAlways: true
    来源
ts
// 即使本地正则校验失败,仍会执行异步校验
const validators = {
  onChange: ({ value }) => !value.includes('@') ? 'Invalid' : undefined,
  onChangeAsync: async ({ value }) => api.check(value),
  asyncAlways: true
}
  • 从表单级校验器返回
    fields
    映射,以便通过单个校验逻辑同时更新多个字段的错误信息 来源
ts
validators: {
  onChange: ({ value }) => ({
    fields: {
      startDate: value.startDate > value.endDate ? 'Must be before end' : undefined,
      endDate: value.startDate > value.endDate ? 'Must be after start' : undefined
    }
  })
}
  • 当表单绑定到动态或异步数据源(如TanStack Query)时,使用响应式对象作为
    defaultValues
    来源
ts
const { data } = useQuery(...)
const defaultValues = reactive({
  name: computed(() => data.value?.name ?? '')
})
const form = useForm({ defaultValues })