v0.1.9

Form 表单

引入import { ErrorListComponent } from '@apollo-design/ui';

具有数据收集、校验和提交功能的表单,包含复选框、单选框、输入框、下拉选择框等元素。

何时使用

  • 需要创建一个原生表单,可能包含各种交互式控件;
  • 提交前需要校验用户输入(同步/异步规则);
  • 需要动态增删表单项(Form.List)。

引入

import { Form, FormItem, FormList, useForm, useWatch, ErrorList } from '@apollo-design/ui';
// 或复合写法
import { Form } from '@apollo-design/ui';
const { Item, List, useForm, useWatch, ErrorList } = Form;

代码演示

加载中…

动态表单 #

Form.List 的默认插槽给出 { fields, operations, meta }:fields 用于 v-for 渲染,operations.add/remove/move 操作行。示例支持增删用户,提交后由 message 给出反馈。

加载中…

嵌套动态表单 #

Form.List 可以嵌套:内层 name 用 [field.name, 'tags'] 定位到父行,字段名路径会按层级展开。示例支持每个用户维护一组标签。

加载中…

监听字段 #

Form.useWatch(name, form) 返回响应式 Ref;示例在两个输入框下方实时显示字段值,无需额外的 @change 处理。

加载中…

字段联动 #

确认密码的 FormItem 声明 dependencies: ['password']:密码变化时会重新校验确认框;validator 从表单实例读取当前密码并返回 Promise。

加载中…

异步校验 #

validator 返回 Promise 时表单进入 validating 状态,has-feedback 显示加载图标;示例输入 admin 会在 600ms 后被拒绝。

加载中…

初始值与重置 #

initialValues 提供非受控初始值;form.setFieldsValue 可以整体回填,form.resetFields 恢复到初始值。

加载中…

提交失败 #

@finishFailed 拿到 errorFields;scrollToFirstError 会自动滚动并聚焦到第一条错误。提交成功与失败都在下方给出可见反馈。

加载中…

读写表单值 #

通过 useForm() 实例调用 getFieldsValue / setFieldsValue,把当前值序列化后展示在页面上;适用于外部按钮触发的批量回填。

加载中…

禁用与尺寸 #

Form 的 disabled 与 size 会级联到所有表单项;示例可实时切换,验证禁用态与三种尺寸。

加载中…

滚动到字段 #

form.scrollToField(name, options) 会把字段滚入最近的滚动容器并聚焦。示例容器限高 240px,点击按钮可直接定位到最后一个字段。

加载中…

复杂表单控件 #

当控件的值与表单存储值不是同一单位时,用 Form.Item 的 getValueProps 把存储值转换成控件展示值,再用 getValueFromEvent 把控件事件转换回存储格式。示例中表单内部以「分」存储金额,InputNumber 展示与输入的是「元」;useWatch('price') 实时显示底层存储值。

加载中…

组件 Token #

通过 ConfigProvider theme.components.Form 设置组件 Token;当前配置会同步作用于 Form 和独立 Form.Item,配置替换或撤除后也会更新。示例共用一份配置展示 vertical 与 inline 布局。需要局部覆盖时仍可在 Form 或 Form.Item 的原生 style 中设置 --apollo-form-* CSS 变量。

加载中…

表单方法调用 #

通过 useForm() 取得表单实例后,可以调用 setFieldsValue、getFieldsValue、validateFields、validateFields({ validateOnly: true }) 与 resetFields。validateFields 校验失败时会 reject,示例捕获 errorFields 并把结果显示在页面上;validateOnly 只执行校验,不返回字段值。

render-props 使默认作用域插槽的 { values, form } 随 store 更新;示例直接显示当前 values,使用外部 useForm() 实例时也会更新。

加载中…

动态表单项 #

useWatch('accountType', form) 监听账号类型,配合 v-if 动态渲染「公司名称」字段。Form.Item 的 rules 只在该字段实际存在时参与校验;切换类型后,已隐藏字段的值不会阻止表单提交。

加载中…

动态增减表单项 #

Form.List 的默认插槽接收 { fields, operations, meta }:fields 用于 v-for 渲染行,operations.add / operations.remove / operations.move 负责增删与排序,meta.errors 汇总列表级校验错误。行内 Form.Item 使用 [field.name, 'name'] 这样的数组 name 与列表项绑定。

加载中…

动态校验规则 #

rules 可以是 computed 计算出的数组。示例用 Switch 切换「普通 / 严格」模式:严格模式追加最小长度与「字母 + 数字」正则规则,Form.Item 会在下一次校验时立即使用新规则。Switch 带 aria-label,保证可访问名称。

加载中…

表单上下文 #

在 Form 的后代组件中调用 useWatch('username') 时无需显式传入 form 实例:useWatch 会通过 Form 提供的上下文字段自动订阅。示例中的 WatchDisplay 是一个独立子组件,用来证明「不传 form 也能读到最新值」。

加载中…

弹窗表单 #

把 Form 放进 Modal,在 @ok 中调用 form.validateFields():校验通过后关闭弹窗并展示提交结果,校验失败则保持弹窗打开,由 Form.Item 显示错误。Modal 的 closable 传入带 aria-label 的对象,保证关闭按钮有可访问名称。

加载中…

嵌套路径 #

Form.Item 的 name 支持数组路径,例如 ['user', 'name'] 与 ['user', 'email'],它们会映射到 { user: { name, email } }。useWatch(['user', 'name'], form) 订阅嵌套值,setFieldsValue({ user: { ... } }) 可以一次写入整棵子树。

加载中…

标签换行 #

Form 的 label-wrap 控制水平布局下标签是否允许换行;配合 label-col / wrapper-col 的栅格比例,可以处理超长标签。示例用 Switch 实时切换 label-wrap,并在页面中显示当前状态。

加载中…

多种布局 #

同一页面可以并列多个 Form,分别设置 layout="inline"、layout="horizontal" 与 layout="vertical"。水平布局使用 label-col / wrapper-col 控制标签与控件的栅格占比;各表单拥有独立的内部 store,字段名互不影响。

加载中…

登录表单 #

一个完整的登录场景:Form.Item 的 rules 校验用户名与密码,Checkbox 通过 value-prop-name="checked" 与布尔字段绑定,提交后由 @finish 展示欢迎信息。Input 使用 autocomplete 与 aria-label 兼顾浏览器自动填充与可访问性。

加载中…

嵌套校验消息 #

Form 的 validate-messages 支持按规则类型嵌套覆盖默认文案:required、types.email、string.min、number.min 分别对应不同校验失败场景。模板变量如 ${name}、${min} 会在运行时替换为字段名和规则参数。

加载中…

必填标记 #

Form 的 required-mark 接受 true、false 或 'optional'。自定义内容使用 #requiredMark="{ label, required }",其中 label 是保留原标签内容的稳定组件,可用 <component :is="label" /> 渲染。示例可实时切换默认标记、隐藏、optional 与自定义插槽。

加载中…

语义化结构样式 #

通过 Form 的 classNames 与 styles 可以分别定制 root / label / content / help / helpItem / extra 六个语义槽。示例同时演示 Form.Item 的 help 与 extra,并用全局样式类覆盖 label 颜色、内容区背景、帮助文字与补充说明。

加载中…

表单变体 #

Form 的 variant 会向下传导给输入控件,可选 outlined、borderless、filled、underlined。示例用 RadioGroup 切换变体,Input 与 Select 会同步更新视觉样式。

加载中…

仅警告校验 #

在规则上设置 warningOnly: true 后,校验失败只会进入 meta.warnings 并展示警告,不会阻止 @finish。示例把「用户名」设为普通必填规则、把「昵称」设为仅警告规则,提交后可观察到两者对提交结果的差异。

加载中…

无表单实例 #

不调用 useForm() 时,Form 会自动创建一个内部 store,Form.Item 的注入与 @finish 仍然正常工作。示例通过改变 key 重新挂载表单来实现重置,并展示 @finish 收集到的字段值。

加载中…

basic #

最基础的表单:Form.Item 包裹控件,rules 声明校验。\n

加载中…

customized-form-controls #

内联表单与提交按钮(html-type="submit")。\n

加载中…

label #

label 定制:required 标记 / optional 文案 / 无 label(control 顶格)/ 无冒号 / tooltip。\n

加载中…

layout #

三种布局:horizontal / vertical / inline。\n

加载中…

validate-status #

校验状态(validateStatus + hasFeedback):错误/警告/校验中。\n

API

FormProps

参数 说明 类型 默认值
form 表单实例(useForm() 创建) FormInstance -
name 表单名(fieldId 前缀 + FormProvider 注册键) string -
layout 布局 'horizontal' | 'vertical' | 'inline' 'horizontal'
labelCol / wrapperCol label / 控件列宽(grid ColProps) ColProps -
labelAlign label 对齐 'left' | 'right' 'right'
labelWrap label 换行 boolean -
colon 冒号(vertical 布局无效) boolean -
requiredMark 必填标记;自定义内容使用 requiredMark 插槽 boolean | 'optional' true
initialValues 初值 object -
validateMessages 校验文案模板 ValidateMessages -
validateTrigger 触发校验的事件 string | string[] | false 'onChange'
preserve 字段卸载后保留值 boolean true
clearOnDestroy 表单卸载时清除值 boolean false
fields 受控字段值及状态;数组替换和字段内更新都会同步 FieldData[] -
disabled 整表禁用 boolean -
size / variant / tooltip 表单态与标签提示配置 - -
scrollToFirstError 校验失败滚动到首个错误字段 boolean | ScrollOptions -
component 容器元素(false 不渲染) string | Component | false 'form'
renderProps 让默认槽的 values 随 store 更新;字段仍处理自身状态与重置 boolean false
classNames / styles 语义槽(root/label/content/help/helpItem/extra)。⚠️ 也接受函数形态((info) => …);根槽与 ConfigProvider components.form 及调用方原生 class / style 合并(原生 style 胜) object | function -

事件(Emits)

finish(values) / finishFailed(errorInfo) / valuesChange(changed, all) / fieldsChange(changed, all);update:* 不适用(值由 store 管理)。

默认作用域插槽为 { values, form }。例如 <Form render-props v-slot="{ values }">…</Form>;普通字段表单可省略 render-props,字段继续独立订阅。

内容槽:requiredMark({ label, required }) 与 feedbackIcon({ status, errors, warnings })。label 是保留原始标签内容的稳定组件,模板中使用 <component :is="label" />。Form.Item 的同名 feedbackIcon 槽优先于 Form 槽;槽撤除后立即恢复当前默认内容。

FormInstance(expose)

getFieldValue / getFieldsValue / setFieldValue / setFieldsValue / resetFields / validateFields / submit / getFieldsError / getFieldError / getFieldWarning / isFieldsTouched / isFieldTouched / isFieldValidating / isFieldsValidating / setFields / getFieldInstance(name) / scrollToField(name, options) / focusField(name) / nativeElement。

getFieldInstance 返回已挂载控件的真实 DOM 或 Vue 公开引用对象(object | undefined),保持调用方模板 ref 的身份;不能假定每个自定义 expose 都有 focus 方法。focusField 在实际支持的能力上聚焦,scrollToField 使用真实控件元素,{ focus: true } 可同时聚焦。nativeElement 是实际 HTML 容器,无容器时为 null。

Form.Item

props:name(NamePath)、rules、dependencies、trigger、valuePropName、getValueFromEvent、getValueProps、normalize、validateTrigger、validateFirst、preserve、initialValue、messageVariables、shouldUpdate;展示:label / labelCol / wrapperCol / colon / required / tooltip / noStyle / help / extra / hasFeedback(boolean)/ validateStatus / hidden / htmlFor / layout。

slots:default({ control, meta, form })(子控件;有 name 时单个控件被注入 value 与事件)、label / help / extra / tooltip / feedbackIcon({ status, errors, warnings })。内容槽优先于对应 prop,显式空槽不会回退到 prop。无字段的布局项也提供同一对象,control 为空、meta 为当前空状态;脱离 Form 的布局项 form 为 undefined。

Form 与有布局壳的 Form.Item 将原生 class/style、属性和监听器落到各自实际根元素。noStyle 项与 Form.List 没有 DOM 根。labelCol/wrapperCol 使用 Grid ColProps 并可携带原生 class/style,嵌套布局项不会继承外层列宽。

事件:reset() / metaChange(meta),分别使用 @reset / @meta-change。组件不手动调用同名回调 Prop。

动态 prefixCls 与布局变更会更新派生类、真实控件的反馈图标、错误/帮助内容,并按已加载 CSS 重新测量 margin 占位。Form.ErrorList 独立使用时读取 ConfigProvider 前缀;在 Form.Item / Form.List 中使用最近的前缀上下文。动态前缀需要预先提供对应的静态 CSS,组件不会生成运行时样式。

Form.List

props:name。scoped slot { fields, operations, meta } —— fields: { name, key, fieldKey }[]、operations: { add, remove, move }、meta: { errors, warnings }。Form.ErrorList 用于展示 List 级错误。

Form.ErrorList 接受 help/errors/warnings 与原生根属性,visibleChanged(visible: boolean) 是所属事件。重复消息保留独立行,离场行使用最后收到的内容,结束后释放布局占位;不再从已经移除的当前 keys 反查消息。

useWatch

useWatch(dependencies, form) 或 useWatch(dependencies, { form, preserve }) —— 返回监听字段路径/selector 的 Ref,随调用它的 effect scope 释放。

useFormInstance() 读取最近 Form 的现有实例;Form 外返回 undefined,不创建新 store。重复 useForm(form) 与直接传给 Form 的同一外建实例共用控件注册表。

开发版直接把 Form / Form.Item 的旧位置参数槽迁为具名对象;requiredMark 内容函数、feedbackIcons 与 hasFeedback.icons 改用上述内容槽,不提供兼容层或弃用期。Form.List 既有对象作用域保持不变。校验器、取值/归一算法与异步业务回调仍是函数。

主题变量

11 个(labelRequiredMarkColor / labelColor / labelFontSize / labelHeight / verticalLabelHeight / labelColonMarginInlineStart / labelColonMarginInlineEnd / itemMarginBottom / verticalLabelPadding / verticalLabelMargin / inlineItemMarginBottom)。

使用 ConfigProvider theme.components.Form 配置,支持当前主题/组件 Token 替换与撤除,并作用于独立 Form.Item。长度数值会转换为 px;verticalLabelHeight 也接受 'auto'。原生 style 中的 --apollo-form-* 变量保留局部覆盖优先级,自定义前缀使用对应的变量前缀。

Powered by Vue 3 + ViteApollo Design · Vue NativeGitHub