
ant-design Form 水平表单实战从Form.create双向绑定到labelCol栅格布局【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/antde/ant-design本篇技术指南基于 ant-design 仓库中 components/form/demo/horizontal-form.md 的「典型表单」示例系统讲解企业级表单最常见的水平排列horizontal形态如何通过Form.create()为组件注入this.props.form如何使用getFieldProps完成表单域与输入控件的双向绑定如何用getFieldsValue收集提交值以及如何借助Form.Item的labelCol/wrapperCol搭建规整的标签-控件栅格布局。读完本文你将能够独立编写一个集输入框、单选框、复选框、文本域、提示气泡于一体的可提交水平表单并理解其背后的源码级实现原理。一、示例总览一个完整的水平典型表单原始示例位于 components/form/demo/horizontal-form.md它演示了 ant-design 表单体系中最核心的用法用Form.create包装组件使组件获得表单实例从而「获取和更新表单提交的数值」。先看完整示例代码import { Form, Input, Button, Checkbox, Radio, Tooltip, Icon } from antd; const FormItem Form.Item; const RadioGroup Radio.Group; let Demo React.createClass({ handleSubmit(e) { e.preventDefault(); console.log(收到表单值, this.props.form.getFieldsValue()); }, render() { const { getFieldProps } this.props.form; const formItemLayout { labelCol: { span: 6 }, wrapperCol: { span: 14 }, }; return ( Form horizontal onSubmit{this.handleSubmit} FormItem {...formItemLayout} label用户名 p classNameant-form-text iduserName nameuserName大眼萌 minion/p /FormItem FormItem {...formItemLayout} label密码 Input typepassword {...getFieldProps(pass)} placeholder请输入密码 / /FormItem FormItem {...formItemLayout} label您的性别 RadioGroup {...getFieldProps(gender, { initialValue: female })} Radio valuemale男的/Radio Radio valuefemale女的/Radio /RadioGroup /FormItem FormItem {...formItemLayout} label备注 help随便写点什么 Input typetextarea placeholder随便写 {...getFieldProps(remark)} / /FormItem FormItem {...formItemLayout} label{span卖身华府 Tooltip title我为秋香Icon typequestion-circle-o //Tooltip /span} label Checkbox {...getFieldProps(agreement)} /同意 /label /FormItem FormItem wrapperCol{{ span: 16, offset: 6 }} style{{ marginTop: 24 }} Button typeprimary htmlTypesubmit确定/Button /FormItem /Form ); } }); Demo Form.create()(Demo); ReactDOM.render(Demo /, mountNode);这个示例虽然篇幅不大却覆盖了表单开发的五个关键知识点表单布局Form horizontal、表单域布局labelCol/wrapperCol、双向绑定getFieldProps、值收集getFieldsValue以及表单域与输入控件的组合Form.ItemInput/RadioGroup/Checkbox。下文逐层拆解。二、Form.create为组件注入表单实例示例的最后一行Demo Form.create()(Demo);是整个表单能力的开关。在 components/form/index.jsx 中可以看到它的实现Form.create (o {}) { const options { ...o, fieldNameProp: id, fieldMetaProp: __meta, }; return createDOMForm(options); };也就是说Form.create是对第三方库rc-form的createDOMForm的一层封装合并用户传入的options并强制注入两个约定——fieldNameProp: id控件字段名取自id属性与fieldMetaProp: __meta字段元信息挂在__meta上。这一点解释了示例中为什么getFieldProps(pass)展开后会给Input自动带上id。包装后的组件能力经过Form.create()包装的组件会自带this.props.form属性该对象提供了完整的表单 API见 components/form/index.md 的 API 表方法说明getFieldsValue获取一组输入控件的值不传参则获取全部组件的值getFieldValue获取单个输入控件的值setFieldsValue设置一组输入控件的值setFields设置一组输入控件的值与 ErrorvalidateFields校验并获取一组输入域的值与 ErrorvalidateFieldsAndScroll校验完成后未通过的域不在可见范围时自动滚动进入可见区getFieldError获取某个输入控件的 ErrorisFieldValidating判断某控件是否处于校验中resetFields重置一组输入控件的值与状态getFieldProps用于和表单进行双向绑定此外Form.create(options)还支持两个常用于对接状态管理的选项参数说明onFieldsChange当Form.Item子节点的值发生改变时触发可把对应值转存到 Redux storemapPropsToFields把 props 转为对应的值用于从 Redux store 中读出值示例的handleSubmit正是使用this.props.form.getFieldsValue()一次性取回所有字段值并打印这是提交表单的标准姿势。三、getFieldProps表单域的双向绑定核心示例中每个受控控件都通过{...getFieldProps(字段名, options)}展开来接入表单Input typepassword {...getFieldProps(pass)} placeholder请输入密码 / RadioGroup {...getFieldProps(gender, { initialValue: female })} Input typetextarea placeholder随便写 {...getFieldProps(remark)} / Checkbox {...getFieldProps(agreement)} /根据 components/form/index.md 的说明getFieldProps返回的属性包括id、value或你设置的其他valuePropName、ref、onChange或你设置的其他trigger/validateTrigger因此不应再手动设置同样的属性以免冲突。getFieldProps的关键选项如下参数说明默认值options.id必填的输入控件唯一标志—options.valuePropName子节点的值的属性名如 Checkbox 是checkedvalueoptions.initialValue子节点的初始值类型由子节点决定—options.trigger收集子节点值的时机onChangeoptions.validateTrigger校验子节点值的时机onChangeoptions.rules校验规则基于 async-validator—两点实战注意不要设置defaultValue初始值应使用initialValue。示例中性别单选框通过initialValue: female让默认选中「女的」。valuePropName因控件而异Input、RadioGroup绑定的是value而Checkbox绑定的则是checked。getFieldProps(agreement)在展开时会依据控件类型自动取用正确的值属性这正是它能与多种控件通用绑定的原因。四、水平布局Form horizontal与栅格示例使用Form horizontal onSubmit{this.handleSubmit}声明水平排列。在 components/form/Form.jsx 的源码中布局由两个布尔属性驱动const formClassName classNames({ [${prefixCls}-horizontal]: this.props.horizontal, [${prefixCls}-inline]: this.props.inline, [className]: !!className, });即horizontal为真时渲染ant-form-horizontal类名inline为真时渲染ant-form-inline。ant-design 表单提供两种排列方式水平排列horizontallabel标签与表单控件水平排布是本文主题行内排列inline表单域表现为inline-block级别的控件多用于搜索栏等紧凑场景。从 style/components/form.less 可以看到水平布局的本质每个.ant-form-item应用make-row即栅格系统的行label与控件区域在行内按列分栏从而实现左右并排.{css-prefix}form-horizontal { .{css-prefix}form-item { .make-row; } .{css-prefix}radio-inline, .{css-prefix}checkbox-inline, .{css-prefix}input { vertical-align: top; } }另一个值得注意的细节Form组件在 Form.jsx 中默认实现了onSubmit(e) { e.preventDefault(); }所以即使你不写handleSubmit表单也不会因回车触发页面刷新。五、labelCol与wrapperCol表单域的栅格分栏示例中将布局参数提取为公共对象再通过展开运算符应用到每个FormItem上这是避免重复书写的推荐做法const formItemLayout { labelCol: { span: 6 }, wrapperCol: { span: 14 }, }; FormItem {...formItemLayout} label用户名labelCollabel 标签的栅格布局设置span/offsetwrapperCol输入控件区域的栅格布局用法与labelCol相同。在 components/form/FormItem.jsx 中FormItem将这两个配置翻译为栅格类名_getLayoutClass(colDef) { if (!colDef) { return ; } const { span, offset } colDef; const col span ? col-${span} : ; const offsetCol offset ? col-offset-${offset} : ; return col offsetCol; }而label与控件容器分别套用这些类名见 FormItem.jsxrenderLabel()把labelCol加到label上renderWrapper()把wrapperCol加到控件包裹层上从而在 24 栅格体系内实现「标签 6 列、控件 14 列」的对齐。示例最后一个表单域提交按钮使用了另一种写法让按钮相对标签列偏移 6 列、占 16 列FormItem wrapperCol{{ span: 16, offset: 6 }} style{{ marginTop: 24 }} Button typeprimary htmlTypesubmit确定/Button /FormItem这里只传wrapperCol而不传labelCol表示该行没有标签、控件从第 7 列开始占 16 列offset: 6与前面labelCol.span 6呼应保证按钮与输入框左对齐。style{{ marginTop: 24 }}则用于给按钮与上方表单项留出间距。说明栅格类名col-*/col-offset-*与 components/layout/col.jsx 中Col组件生成的类名规则一致FormItem只是直接复用了这套栅格约定无需额外引入Row/Col。六、FormItem的表单域能力label、help 与校验联动Form.Item是表单域容器除了栅格布局还承担提示与校验反馈职责。在 components/form/FormItem.jsx 中可以看到其完整的属性支持参数说明类型 / 可选值默认值labellabel 标签的文本string / node—labelCollabel 标签布局如{span: 6, offset: 12}object—wrapperCol输入控件区域的布局用法同labelColobject—help提示信息不设置时按校验规则自动生成string—extra额外的提示信息与 help 类似可同时展示错误与提示string—required是否必填不设置时按校验规则自动生成boolfalsevalidateStatus校验状态不设置时自动生成success/warning/error/validating—hasFeedback配合validateStatus展示校验状态图标boolfalseprefixCls样式类名前缀stringant-form示例中「备注」字段演示了help的静态用法FormItem {...formItemLayout} label备注 help随便写点什么其渲染逻辑在 FormItem.jsx 中当未显式传help且存在表单上下文时会自动拼接context.form.getFieldError(...)的错误信息显式传help则直接展示。也就是说help 优先展示手动提示缺省时退化为错误提示。与此同时FormItem会自动监听字段状态getValidateStatus字段校验中显示validating、有错误显示error、已有值显示success并配合hasFeedback在控件右侧渲染状态图标必填星号则由 renderLabel 依据校验规则中的required自动判定.ant-form-item-required样式见 style/components/form.less。此外FormItem还会自动将函数类型的子控件放大为size: large见 renderChildren。这与 ant-design「标准表单中一律使用大号控件」的设计一致——在表单内输入框高度固定为 32px相关样式约束见 style/components/form.less。七、多种控件组合Input、RadioGroup、Checkbox 与富文本 label示例中的「用户名」字段展示了只读文本表单域的写法直接使用p classNameant-form-text渲染纯文本。该类的样式为行内块元素见 style/components/form.less适用于展示固定信息而非输入的场景。「您的性别」字段演示了RadioGroup与getFieldProps的组合通过initialValue: female设定默认选中项。示例最后一行还展示了一个技巧——label属性接收 React 节点而非纯字符串将Tooltip与Icon嵌入标签label{span卖身华府 Tooltip title我为秋香Icon typequestion-circle-o //Tooltip /span}这让「复杂标签」成为可能标签右侧附带气泡提示鼠标悬停显示说明文字是企业级表单常见的交互细节。「密码」与「备注」两个字段分别演示了Input的两种形态Input typepassword {...getFieldProps(pass)} placeholder请输入密码 / Input typetextarea placeholder随便写 {...getFieldProps(remark)} /在 components/input/index.jsx 中Input依据type属性决定渲染原生input还是textareatype默认值为textInput.defaultProps。因此文档特别强调只有正确设置了type属性的输入控件才能获得正确样式——不设type时组件直接渲染 children不会产出输入框。延伸阅读想一次性看齐所有支持的表单控件Select、Checkbox 组合、RadioGroup 组合等可对照同目录下的 components/form/demo/form-controls.md输入框三种尺寸large / default / small的对比见 components/form/demo/input.md其中也再次强调「表单内只使用大尺寸32px」。八、提交流程与源码依据小结把示例串起来一个水平典型表单的完整工作流是注入表单Demo Form.create()(Demo)组件获得this.props.form绑定字段每个控件通过getFieldProps(name, options)展开获得id、value、onChange等属性与表单内部状态双向绑定声明布局Form horizontal开启水平排列FormItem的labelCol/wrapperCol完成标签与控件的栅格分栏收集提交onSubmit中调用e.preventDefault()阻止默认刷新再用getFieldsValue()获取全部字段值示例中打印到控制台可选校验在getFieldProps的rules中声明校验规则FormItem自动联动展示错误、必填星号与校验状态图标。相关的核心实现文件路径汇总如下便于深入阅读示例文档components/form/demo/horizontal-form.md组件入口与Form.createcomponents/form/index.jsx表单容器horizontal / inline 布局components/form/Form.jsx表单域label / help / 校验状态 / 栅格components/form/FormItem.jsxAPI 说明components/form/index.md输入框实现type 分支与尺寸components/input/index.jsx水平 / 行内布局与校验态样式style/components/form.less至此你已掌握 ant-design 水平表单从「注入实例、绑定字段、栅格布局、控件组合到提交取值」的完整链路可以基于这套模式快速搭建并扩展企业级数据录入表单。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/antde/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考