tanstack-vue-form-skilld
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTanStack/form @tanstack/vue-form
@tanstack/vue-formTanStack/form @tanstack/vue-form
@tanstack/vue-formVersion: 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:— v1.28.0 flattens errors by default (
field.errorsnot[error]), use[[error]]to restore old nested behavior sourcedisableErrorFlat: true -
DEPRECATED:— use
field.getValue()instead as direct accessor methods on FieldApi are deprecated in favor of state access sourcefield.state.value -
NEW:— validates field value against Standard Schema V1 without affecting internal field error state source
field.parseValueWithSchema() -
NEW:— form-level Standard Schema V1 validation helper for third-party schemas like Zod or Valibot source
form.parseValuesWithSchema() -
NEW:— helper to define reusable, type-safe form options with inference outside of the
formOptions()hook sourceuseForm -
NEW:component — declarative Vue component alternative to
Fieldfor defining form fields directly in templates sourceuseField -
NEW:component — Vue component for fine-grained subscriptions to form or field state changes to optimize re-renders source
Subscribe -
NEW:— Vue hook providing direct, reactive access to the underlying TanStack Store state for the form or field source
useStore() -
NEW:—
resetField()method to reset a specific field's value and metadata back to its default state sourceFormApi -
NEW:—
clearFieldValues()utility to efficiently remove all items from an array field's data sourceFormApi -
NEW:— allows manual overriding of the internal validation error map for custom validation logic source
setErrorMap() -
NEW:— native support for the Standard Schema validation protocol across all validator fields source
StandardSchemaV1 -
NEW:option —
modenow supports explicitUseFieldOptionsor'value'modes for better type safety in complex forms'array' -
NEW:— new option in
disableErrorFlatto opt-out of automatic error flattening introduced in v1.28.0 sourceFieldApiOptions
Also changed: new helper · array utility · array utility · array utility · metadata helper · interface stabilization · interface stabilization
resetFieldMeta()insertFieldValue()moveFieldValues()swapFieldValues()FieldApi.getInfo()VueFieldApiVueFormApi本节记录各版本的API变更。
@tanstack/vue-form-
破坏性变更:— v1.28.0版本默认将错误信息扁平化(变为
field.errors而非[error]),可设置[[error]]恢复旧的嵌套格式 来源disableErrorFlat: true -
已废弃:— 请改用
field.getValue(),因为FieldApi上的直接访问方法已被废弃,推荐使用状态访问方式 来源field.state.value -
新增:— 依据Standard Schema V1验证字段值,且不会影响字段内部的错误状态 来源
field.parseValueWithSchema() -
新增:— 表单级别的Standard Schema V1验证工具,支持Zod或Valibot等第三方校验库 来源
form.parseValuesWithSchema() -
新增:— 用于在
formOptions()钩子外部定义可复用、类型安全的表单选项,并支持类型推断的工具函数 来源useForm -
新增:组件 — 声明式Vue组件,可替代
Field,用于在模板中直接定义表单项 来源useField -
新增:组件 — Vue组件,用于对表单或字段的状态变更进行细粒度订阅,以优化重渲染性能 来源
Subscribe -
新增:— Vue钩子,提供对表单或字段底层TanStack Store状态的直接响应式访问 来源
useStore() -
新增:—
resetField()方法,用于将指定字段的值和元数据重置回默认状态 来源FormApi -
新增:—
clearFieldValues()工具函数,用于高效清空数组字段中的所有数据项 来源FormApi -
新增:— 允许手动覆盖内部校验错误映射,以实现自定义校验逻辑 来源
setErrorMap() -
新增:— 所有校验字段原生支持Standard Schema校验协议 来源
StandardSchemaV1 -
新增:选项 —
mode现在支持显式的UseFieldOptions或'value'模式,以提升复杂表单的类型安全性'array' -
新增:—
disableErrorFlat中的新选项,用于选择退出v1.28.0版本引入的自动错误扁平化功能 来源FieldApiOptions
**其他变更:**新增工具函数 · 新增数组工具 · 新增数组工具 · 新增数组工具 · 元数据工具优化 · 接口稳定化 · 接口稳定化
resetFieldMeta()insertFieldValue()moveFieldValues()swapFieldValues()FieldApi.getInfo()VueFieldApiVueFormApiBest Practices
最佳实践
- Use to define type-safe, reusable form configurations that can be shared across components or used for better type inference source
formOptions()
ts
const options = formOptions({
defaultValues: { email: '' },
validators: {
onChange: z.object({ email: z.string().email() })
}
})
const form = useForm(options)- Link field validations with to trigger re-validation when dependent field values change, such as password confirmations source
onChangeListenTo
vue
<form.Field
name="confirm_password"
:validators="{
onChangeListenTo: ['password'],
onChange: ({ value, fieldApi }) =>
value !== fieldApi.form.getFieldValue('password') ? 'Passwords do not match' : undefined
}"
>- Implement at the field or validator level to throttle expensive asynchronous validation calls like API checks source
async-debounce-ms
vue
<form.Field
name="username"
:async-debounce-ms="500"
:validators="{
onChangeAsync: async ({ value }) => checkUsername(value)
}"
>- Parse Standard Schemas manually within to retrieve transformed values, as the form state preserves the raw input data source
onSubmit
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 to differentiate between multiple submission actions within a single
onSubmitMetahandler sourceonSubmit
vue
<button @click="form.handleSubmit({ action: 'save_draft' })">Save Draft</button>
<button @click="form.handleSubmit({ action: 'publish' })">Publish</button>- Combine with
canSubmitto ensure the submit button remains disabled until the user has actually interacted with the form sourceisPristine
vue
<template v-slot="{ canSubmit, isPristine }">
<button :disabled="!canSubmit || isPristine">Submit</button>
</template>- Use with a selector in
form.useStorefor granular, reactive access to form state without re-rendering on unrelated changes source<script setup>
ts
const canSubmit = form.useStore((state) => state.canSubmit)- Enable when you need asynchronous validators to execute regardless of whether synchronous validation has already failed source
asyncAlways: true
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 mapping from form-level validators to update errors across multiple fields simultaneously from a single validation logic source
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
}
})
}- Use reactive objects for when binding the form to dynamic or asynchronous data sources like TanStack Query source
defaultValues
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
}"
>- 在字段或校验器级别设置,以节流耗时的异步校验调用(如API检查) 来源
async-debounce-ms
vue
<form.Field
name="username"
:async-debounce-ms="500"
:validators="{
onChangeAsync: async ({ value }) => checkUsername(value)
}"
>- 在中手动解析Standard Schemas以获取转换后的值,因为表单状态会保留原始输入数据 来源
onSubmit
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 })