表单数据
表单中有三种“版本”的数据和两组错误。本页说明它们分别是什么,以及在填写过程中如何变化。以下所有值都是 tinyval-vue 的真实输出。
ts
const Signup = object({
name: pipe(string(), trim(), minLength(2)),
email: pipe(string(), email()),
age: optional(pipe(coerce.number(), min(18))),
});
const form = useForm(Signup, { initial: { name: '', email: '', age: '' } });values、data 和 changes
| 字段 | 内容 | 示例 | 用途 |
|---|---|---|---|
form.values | 用户输入的原始内容 | { name: ' Ivan ', email: 'ivan@mail.ru', age: '30' } | v-model |
form.data | 经过 Schema 校验后的数据:trim、coerce、无多余字段。存在错误时为 undefined | { name: 'Ivan', email: 'ivan@mail.ru', age: 30 } | 预览、计算 |
handleSubmit 中的数据 | 与 form.data 相同,取提交时的值 | { name: 'Ivan', email: 'ivan@mail.ru', age: 30 } | 发送到服务端 |
form.changes | 只包含修改过的字段,保持输入原样(来自 values) | { email: 'petr@mail.ru' } | PATCH —— 见 编辑 |
values 的类型来自 initial(输入框中是字符串),data 的类型来自 Schema(age: number)。
errors 和 allErrors
| 字段 | 内容 |
|---|---|
form.allErrors | Schema 和服务端的全部当前错误 —— 立即可用,甚至在用户输入之前 |
form.errors | 只包含应显示的错误:用户离开过的字段,提交后则全部显示。另外还包括服务端错误 |
格式与 tinyval 的 errors 相同:点分隔路径 → 第一个错误的文本。路径和文本的详细说明见 校验结果。
状态如何变化
用户填写注册表单:
| 步骤 | errors | allErrors | valid | dirty | submitted | submitCount | submitSucceeded | data |
|---|---|---|---|---|---|---|---|---|
| 1. 打开表单 | {} | name、email:Required | false | false | false | 0 | false | undefined |
2. 在姓名中输入 ' I' | {} | name:Must be at least 2 characters long,email:Required | false | true | false | 0 | false | undefined |
| 3. 离开姓名字段 | name:Must be at least 2 characters long | 同步骤 2 | false | true | false | 0 | false | undefined |
| 4. 点击“提交” | name、email —— 全部错误可见 | 同步骤 2 | false | true | true | 1 | false | undefined |
| 5. 修正后服务端返回 422 | email:The email has already been taken. | 相同 | false | true | true | 2 | false | { name: 'Ivan', … } |
| 6. 修改邮箱后提交 | {} | {} | true | false | true | 3 | true | { name: 'Ivan', email: 'petr@mail.ru', age: 30 } |
从表中可以看出:
- 错误会立即计算(步骤 1 的
allErrors),但只在用户离开字段或点击“提交”时显示。 - 服务端错误会进入
errors并使valid为 false,但data仍然存在 —— 数据已通过 Schema 校验。用户修改该字段后错误会消失。 - 成功提交后
dirty重新变为false,changes为空:当前值被视为已保存。
handleSubmit 收到什么
只有在表单校验通过时才会调用,且只包含校验后的数据 —— 已经过 trim 和 coerce:
ts
// form.values: { name: ' Ivan ', email: 'petr@mail.ru', age: '30' }
const submit = form.handleSubmit((data) => {
data; // { name: 'Ivan', email: 'petr@mail.ru', age: 30 }
});传给 onInvalid 的错误是提交时的可见错误(form.errors),也就是全部错误。
其他字段
| 字段 | 值 |
|---|---|
touched | 用户离开过的字段:{ name: true }。路径格式与 errors 相同 |
validating | 异步检查进行中时为 true |
submitting | handleSubmit 处理函数执行期间为 true |
id | 字段 id 的前缀 |
完整列表见 useForm。