Form 表单
用于收集、校验和提交一组输入项。validateDebounce / normalize 等边角能力后续迭代。
基本使用
表单校验
初始值和依赖校验
函数式 rules
rules 接受工厂函数 (model) => Rule | Rule[],每次校验时执行,可基于当前 form model 派生动态规则。常见场景:confirm 字段对比 password、互斥字段(A 填了 B 必填)、长度跟随类型变化。
warningOnly 警告级规则
规则上加 warningOnly: true,校验失败时 FormItem 状态降级为 warning,不阻塞 form-level submit。适合「弱密码提醒」「价格异常但允许通过」等需要提示却不强制拦截的场景。
hasFeedback 校验状态图标
hasFeedback=true 在控件右侧显示对应状态图标(✓ success / ✕ error / ! warning / ◌ validating);可在 Form 级开关后所有 FormItem 默认显示,单 FormItem 可显式覆盖。
必填 / 可选标记
requiredMark 控制必填提示策略:true(默认,必填字段左侧加 *)/ false(不显示任何标记)/ 'optional'(非必填字段右侧加 (optional),移动端常用)。
动态字段 Form.List
通过 <c-form-list> 管理一组同构字段。默认作用域插槽提供 (fields, { add, remove, move }),每个 field 包含 key(稳定 key,移动后保持)和 name(当前下标,参与 name path 拼接)。
不同布局
layout 切换 horizontal(默认)/ vertical(标签在上,输入在下,常用于移动端)/ inline(行内紧凑布局,filter / search 场景)。
栅格 labelCol / wrapperCol
labelCol / wrapperCol 接收 24 栅格对象 { span?, offset?, flex? },按 (span/24)*100% 换算为宽度,比 labelWidth 的单一像素方案更适合响应式表单。Form 级配置作为默认;FormItem 显式同名 prop 优先覆盖。
全表 disabled / 提交中态切换
disabled 在 Form 级开启会给整个 form 加上 disabled 样式标记,配合「保存中锁表」「待审核只读」业务非常常见。
实例方法
通过 ref 拿到 FormInstance,可调用 validate / resetFields / clearValidate / scrollToField 等方法。
跨表单联动 Form.Provider
<c-form-provider> 包裹多个具名 <c-form>,在子表单提交成功后通过 form-finish 聚合 forms 注册表,常用于"同一页面里 A 表单提交后用 B 表单的当前值做联动"的场景。
form-change 在任意字段值变化时触发,回调签名同 form-finish。
<script setup lang="ts">
import { reactive } from 'vue'
const profile = reactive({ name: '' })
const billing = reactive({ address: '' })
function onFinish(name: string, info: { values: any; forms: Record<string, any> }) {
if (name === 'profile') {
billing.address = info.forms.billing.getFieldsValue().address
}
}
</script>
<template>
<c-form-provider @form-finish="onFinish">
<c-form name="profile" :model="profile">
<c-form-item name="name"><c-input v-model="profile.name" /></c-form-item>
<c-button native-type="submit">Save</c-button>
</c-form>
<c-form name="billing" :model="billing">
<c-form-item name="address"><c-input v-model="billing.address" /></c-form-item>
</c-form>
</c-form-provider>
</template>字段保留策略 preserve
Form 默认在字段卸载时保留 model 中的值(preserve=true)。把 preserve=false 配置在表单上则全表单字段卸载即清理,单个 c-form-item 上的 preserve 优先于表单级配置:
<c-form :model="model" :preserve="false">
<c-form-item v-if="advanced" name="apiKey" :preserve="true">
<c-input v-model="model.apiKey" />
</c-form-item>
</c-form>参数
Form
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| model | object | {} | 表单数据对象 |
| rules | FormRules | {} | 表单校验规则 |
| initialValues | object | {} | 表单初始值 |
| labelWidth | string / number | -- | 标签宽度(简单场景);labelCol 优先级更高 |
| labelCol | { span?: number; offset?: number; flex?: string | number } | -- | 24 栅格布局的 label 列配置,按 (span/24)*100% 换算为 width |
| wrapperCol | 同 labelCol | -- | 表单控件区列配置 |
| labelPosition | left / right / top | right | 标签位置 |
| layout | horizontal / vertical / inline | horizontal | 表单布局 |
| disabled | boolean | false | 禁用态样式标记 |
| colon | boolean | true | 是否显示标签冒号 |
| requiredMark | boolean / 'optional' | true | 必填/可选标记显示策略 |
| hasFeedback | boolean | false | 校验状态图标(FormItem 显式优先;图标随 currentStatus 切) |
| validateMessages | FormValidateMessages | {} | 校验消息模板 |
| validateOnRuleChange | boolean | true | 规则变化时清理校验状态 |
| scrollToFirstError | boolean / ScrollIntoViewOptions | false | 校验失败时滚动到首个错误字段 |
| name | string | -- | 表单名(接入 FormProvider) |
| preserve | boolean | true | 字段卸载时是否保留 model 值 |
FormItem
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| name | string / number / array | -- | 字段路径,支持数组路径 |
| label | string | -- | 标签文本 |
| labelCol | 同 Form 同名 prop | -- | 当前项 label 列配置(显式优先于 Form 级) |
| wrapperCol | 同 Form 同名 prop | -- | 当前项控件列配置 |
| initialValue | any | -- | 字段初始值 |
| required | boolean | false | 是否必填 |
| rules | FormRule | FormRule[] | ((model) => FormRule | FormRule[]) | -- | 字段校验规则(支持函数式动态生成) |
| help | string | -- | 帮助或外部错误文案 |
| extra | string | -- | 额外提示文案 |
| validateStatus | success / error / warning / validating | -- | 外部校验状态(含 warning,配合 warningOnly rule) |
| hasFeedback | boolean | 跟随 Form | 校验状态图标(图标 ✓ / ✕ / ! / ◌ 随 currentStatus 切,input padding-right 让位) |
| dependencies | FormNamePath[] | [] | 依赖字段变化后重新校验当前项 |
| validateDebounce | number | -- | 触发校验的 debounce ms |
| normalize | (value, prevValue, allValues) => any | -- | 在校验/提交前 normalize 值 |
| htmlFor | string | -- | label 的 for 属性 |
| colon | boolean | 跟随 Form | 是否显示当前项冒号 |
| hidden | boolean | false | 隐藏字段但保留注册 |
| noStyle | boolean | false | 不显示标准表单项样式 |
| preserve | boolean | 跟随 Form | 字段卸载是否保留值,覆盖表单级配置 |
未实现的 API:
valuePropName/getValueFromEvent/getValueProps—— Vue 的v-model已统一协议。Vue 响应式自动处理依赖收集,无需shouldUpdate。
FormRule.warningOnly: boolean:失败时降级为warning,不阻塞 form-level submit。
FormRule
| 字段 | 类型 | 说明 |
|---|---|---|
| required | boolean | 是否必填 |
| message | string | 校验失败提示文案(不传时走 validateMessages 模板) |
| trigger | 'change' / 'blur' / 'submit' 或其数组 | 触发时机 |
| type | 'string' / 'number' / 'boolean' / 'array' / 'object' / 'email' / 'url' | 类型校验 |
| min / max | number | 长度(string / array)或数值上下限 |
| len | number | 精确长度 |
| pattern | RegExp | 正则校验 |
| enum | any[] | 枚举校验 |
| whitespace | boolean | 是否拒绝纯空白字符串 |
| warningOnly | boolean | 失败时降级为 warning 状态,不阻塞 form-level submit |
| validator | (rule, value, model) => boolean | string | Error | Promise<...> | 自定义同步 / 异步校验函数(返回 false / string 视为失败) |
FormList
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| name | string / number / array | -- | 列表字段路径 |
| initialValue | any[] | -- | 列表初始值(model 中无值时使用) |
默认作用域插槽签名:(fields: { key, name }[], { add, remove, move })。add(value?, insertIndex?) / remove(index | indices) / move(from, to) 直接修改 model[name] 数组并维持稳定 key。
FormProvider
无 props。事件:
| 事件 | 回调签名 | 说明 |
|---|---|---|
| form-change | (name, { changedFields, forms }) | 任意字段变化触发 |
| form-finish | (name, { values, forms }) | 子表单 submit 校验通过触发 |
forms 是 Record<string, FormInstance>,FormInstance 暴露 validate / validateField / resetFields / clearValidate / scrollToField / getFieldsValue。
方法
| 方法 | 说明 |
|---|---|
| validate | 校验全部字段 |
| validateField | 校验指定字段 |
| resetFields | 重置字段值和状态 |
| clearValidate | 清理校验状态 |
| scrollToField | 滚动到指定字段 |
事件
| 事件 | 说明 |
|---|---|
| submit | 表单提交后触发 |
| validate | 字段校验完成后触发 |
| validate-failed | 表单校验失败后触发 |
| values-change | 字段触发原生 change 时携带 { name, value } 抛出 |
已完成功能
- 表单数据、规则、初始值、校验消息模板和禁用态上下文。
- 字段注册/卸载、全量校验、字段校验、重置、清理校验和滚动到字段。
- submit 自动校验、校验成功/失败事件、字段级 validate 事件。
prop和name字段路径,支持字符串、数字、数组路径和a[0].b写法。- required、type、email、url、enum、whitespace、min、max、len、pattern、自定义同步/异步 validator。
- blur/change/submit 触发器过滤。
- horizontal/vertical/inline 布局、label 宽度/位置、冒号、必填/可选标记。
- FormItem 的 help、extra、validateStatus、htmlFor、hidden、noStyle、dependencies。
Form.List动态字段增删/移动、稳定 key、initialValue、与父级 name path 自动拼接。Form.Provider跨表单注册表与form-change/form-finish聚合。- form-level 与 item-level 双层
preserve控制字段卸载值。 warningOnly规则降级、hasFeedback状态图标、labelCol/wrapperCol24 栅格。- 函数式
rules: (model) => Rule | Rule[]。 - 基础 ARIA 错误状态和错误消息
role="alert"。
缺失功能
- render props 级别的复杂条件渲染。
validateDebounce、normalize、getValueProps等少量高级字段配置。- 完整无障碍实现和与所有录入组件的深度状态联动。
- 更完整的滚动容器定位、复杂错误聚合展示和国际化包级别默认文案。