多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Formily Next Space 组件指南:基于 Flex 的表单元素并排布局方案

Formily Next Space 组件指南:基于 Flex 的表单元素并排布局方案 前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载Space 是 formily/next 中基于 Flex 布局的轻量排版组件用于将任意元素快速并排或纵向排列是表单内“姓名分栏输入”“单位拼接”等场景的常用工具。阅读本文后你将掌握 Space 的三种 Schema 写法Markup Schema / JSON Schema / Pure JSX、完整 API 参数语义以及它与 FormLayout.spaceGap 联动、默认尺寸映射等底层实现原理。Space 组件在 Formily 生态中承担着“无数据节点编排”的职责它本身不绑定任何表单字段而是作为一个纯布局容器将多个字段横向或纵向排布在同一视觉行内。与FormGrid栅格系统不同Space 关注的是紧凑、等间距的元素序列非常适合姓 名、单位 数值、多个附加后缀输入框等场景。一、组件定位Void 节点上的布局容器从源码结构看Space 是一个不产生字段值的布局组件。在 packages/next/src/space/index.tsx 中它接收children后通过toArray将子元素展开并为每个子元素包裹space-item容器{toArray(props.children, { keepEmpty: true }).map((child, index) ( div className{${prefix}-item} key{index} {child} /div ))}因此在使用时Space 必须挂载在VoidField / void 类型节点上x-componentSpace其子节点才是真正参与表单的字段。这保证了布局节点不会污染表单数据模型是 Formily “布局与数据分离”设计理念的典型体现。二、Markup Schema 用法Markup Schema 是 Formily React 中最直观的声明式写法。将Space注册进createSchemaField的 components 后即可在SchemaField.Void上使用import React from react import { Input, FormItem, FormLayout, FormButtonGroup, Submit, Space, } from formily/next import { createForm } from formily/core import { FormProvider, createSchemaField } from formily/react const SchemaField createSchemaField({ components: { Input, FormItem, Space, }, }) const form createForm() export default () ( FormProvider form{form} FormLayout labelCol{6} wrapperCol{16} SchemaField SchemaField.Void titlename x-decoratorFormItem x-decorator-props{{ asterisk: true, feedbackLayout: none, }} x-componentSpace SchemaField.String namefirstName x-decoratorFormItem x-componentInput required / SchemaField.String namelastName x-decoratorFormItem x-componentInput x-visible{{$values.firstName 123}} required / SchemaField.String namekk x-decoratorFormItem x-componentInput x-decorator-props{{ addonAfter: Unit, }} required / /SchemaField.Void SchemaField.Void titleText concatenation x-decoratorFormItem x-decorator-props{{ asterisk: true, feedbackLayout: none, }} x-componentSpace SchemaField.String nameaa x-decoratorFormItem x-componentInput x-decorator-props{{ addonAfter: Unit, }} required / SchemaField.String namebb x-decoratorFormItem x-componentInput x-decorator-props{{ addonAfter: Unit, }} required / SchemaField.String namecc x-decoratorFormItem x-componentInput x-decorator-props{{ addonAfter: Unit, }} required / /SchemaField.Void SchemaField.String nametextarea titletext box x-decoratorFormItem required x-componentInput.TextArea x-component-props{{ style: { width: 400, }, }} / /SchemaField FormButtonGroup.FormItem Submit onSubmit{console.log}Submit/Submit /FormButtonGroup.FormItem /FormLayout /FormProvider )要点解析每个SchemaField.Void用x-componentSpace声明布局容器x-decoratorFormItem让整个 Space 拥有统一的标签与校验反馈区域子字段通过name独立绑定表单数据彼此互不影响x-visible{{$values.firstName 123}}演示了字段联动当 firstName 的值等于123时lastName 才显示这验证了 Space 内的字段依然完整参与 Formily 的响应式联动体系addonAfter: Unit用于给输入框追加单位后缀形成“数值 单位”的拼接观感。三、JSON Schema 用法当 Schema 以纯 JSON 形式存在如后端下发、动态渲染时Space 的声明方式转换为type: voidx-component: Spaceimport React from react import { Input, FormItem, FormLayout, FormButtonGroup, Submit, Space, } from formily/next import { createForm } from formily/core import { FormProvider, createSchemaField } from formily/react const SchemaField createSchemaField({ components: { Input, FormItem, Space, }, }) const form createForm() const schema { type: object, properties: { name: { type: void, title: Name, x-decorator: FormItem, x-decorator-props: { asterisk: true, feedbackLayout: none, }, x-component: Space, properties: { firstName: { type: string, x-decorator: FormItem, x-component: Input, required: true, }, lastName: { type: string, x-decorator: FormItem, x-component: Input, required: true, }, }, }, texts: { type: void, title: Text concatenation, x-decorator: FormItem, x-decorator-props: { asterisk: true, feedbackLayout: none, }, x-component: Space, properties: { aa: { type: string, x-decorator: FormItem, x-decorator-props: { addonAfter: Unit, }, x-component: Input, required: true, }, bb: { type: string, x-decorator: FormItem, x-decorator-props: { addonAfter: Unit, }, x-component: Input, required: true, }, cc: { type: string, x-decorator: FormItem, x-decorator-props: { addonAfter: Unit, }, x-component: Input, required: true, }, }, }, textarea: { type: string, title: Text box, x-decorator: FormItem, x-component: Input.TextArea, x-component-props: { style: { width: 400, }, }, required: true, }, }, } export default () ( FormProvider form{form} FormLayout labelCol{6} wrapperCol{16} SchemaField schema{schema} / FormButtonGroup.FormItem Submit onSubmit{console.log}Submit/Submit /FormButtonGroup.FormItem /FormLayout /FormProvider )JSON Schema 与 Markup Schema 在语义上完全等价type: void对应 Markup 中的SchemaField.Voidproperties对应 JSX 子节点。这种等价性让同一份表单既能静态写在 JSX 里也能由后端动态下发渲染是 Formily 动态表单能力的核心。四、Pure JSX 用法如果不想使用 Schema 体系可以直接用formily/react的Field/VoidField以命令式 JSX 构建等价表单import React from react import { Input, FormItem, FormLayout, FormButtonGroup, Submit, Space, } from formily/next import { createForm } from formily/core import { FormProvider, Field, VoidField } from formily/react const form createForm() export default () ( FormProvider form{form} FormLayout labelCol{6} wrapperCol{16} VoidField namename titlename decorator{[ FormItem, { asterisk: true, feedbackLayout: none, }, ]} component{[Space]} Field namefirstName decorator{[FormItem]} component{[Input]} required / Field namelastName decorator{[FormItem]} component{[Input]} required / /VoidField VoidField nametexts titleText concatenation decorator{[ FormItem, { asterisk: true, feedbackLayout: none, }, ]} component{[Space]} Field nameaa decorator{[ FormItem, { addonAfter: Unit, }, ]} component{[Input]} required / Field namebb decorator{[ FormItem, { addonAfter: Unit, }, ]} component{[Input]} required / Field namecc decorator{[ FormItem, { addonAfter: Unit, }, ]} component{[Input]} required / /VoidField Field nametextarea titletext box decorator{[FormItem]} component{[ Input.TextArea, { style: { width: 400, }, }, ]} required / FormButtonGroup.FormItem Submit onSubmit{console.log}Submit/Submit /FormButtonGroup.FormItem /FormLayout /FormProvider )Pure JSX 写法中VoidField的component{[Space]}声明布局组件decorator{[FormItem, {...}]}声明装饰器及参数Field的component{[Input]}声明字段组件。它与 Schema 写法共享同一个底层字段模型三种写法可在同一表单中混用。五、API 详解与源码级实现原理5.1 属性总览Space 的属性定义位于 packages/next/src/space/index.tsx 的ISpaceProps接口完整参数如下属性名类型说明默认值styleCSSProperties自定义样式-classNamestring自定义 class 名-prefixstring样式前缀truesizenumber \|small \|large \|middle子元素间隔大小8pxdirectionhorizontal \|vertical排列方向horizontalalignstart \|end \|center \|baseline交叉轴对齐方式startwrapboolean是否自动换行false5.2 size间隔尺寸的三种解析路径size的解析逻辑直接体现了 Space 与 FormLayout 的联动设计const spaceSize { small: 8, middle: 16, large: 24, } const _size size ?? layout?.spaceGap ?? 8显式传值传入数字如size{12}时直接作为间隔像素传入枚举字符串时通过spaceSize映射small8px、middle16px、large24px继承 FormLayout未传size时自动读取useFormLayout()返回的spaceGap即上层 FormLayout 的spaceGap?: number配置见其IFormLayoutProps接口实现整表统一间距兜底默认值两层都没有时回退到8px。最终间隔通过isNumberLike判定后传给alifd/next的Box组件的spacing属性落地。5.3 direction 与 alignFlex 方向与对齐direction与align会被转换为 Box 的 Flex 语义const getDirection () (direction horizontal ? row : column) const getAlign () { if (align start) return flex-start if (align end) return flex-end return center }directionhorizontal→row横向并排默认vertical→column纵向堆叠align映射到 Flex 的align-itemsstart→flex-start默认、end→flex-end、center→centerbaseline交由 Box 原生处理容器根元素强制display: inline-flex因此 Space 可以像内联元素一样被嵌入到文本流或按钮组中同时内部保持 Flex 布局。5.4 prefix 与样式细节usePrefixCls(space, props)生成space样式前缀可通过prefix覆盖每个子元素被包裹在div classxxx-space-item中。对应样式 packages/next/src/space/main.scss 只有一个关键规则.#{$space-prefix-cls}-item:empty { display: none !important; }即空子元素自动隐藏。这意味着当联动导致某个字段被隐藏如示例中 lastName 的x-visible条件不满足时它在 Space 中不会留下空白占位布局不会出现空洞。样式入口见 packages/next/src/space/style.ts它引入alifd/next/lib/box/style与main.scss。5.5 与 FormLayout 的联动spaceGap这是 Space 最值得关注的继承特性在 packages/next/src/form-layout/index.tsx 中FormLayout通过FormLayoutDeepContext/FormLayoutShallowContext双层 Context 向下传递布局配置useFormLayout合并两层取值spaceGap正是其中之一。因此你可以在FormLayout上统一设置FormLayout spaceGap{12} {/* 所有未显式传 size 的 Space 都会使用 12px 间隔 */} /FormLayout从源码结构看这保证了“整表间距统一”只需一处配置即可生效而单个 Space 仍可通过自身size覆盖全局值兼顾全局一致性与局部定制。5.6 多端实现对照需要说明的是Space 在各 UI 库适配包中均有实现且保持一致的 API 心智formily/antdpackages/antd/src/space/index.tsx直接透传 antd 的Space组件同样接入useFormLayout的spaceGap作为默认sizeformily/next本文主体基于alifd/next的Box封装增加direction、align、wrap等语义化参数。两者共享同一套size ?? spaceGap取值策略切换 UI 库时无需改动业务用法。六、典型使用建议姓名分栏姓、名分别作为 Space 子字段保持独立校验与数据键数值 单位利用addonAfter在输入框后拼接单位多个字段并排形成“测量值序列”联动隐藏结合x-visible表达式动态显隐子字段配合space-item:empty的隐藏规则布局自动收拢无需手动管理占位整表间距优先通过FormLayout.spaceGap统一配置局部再以size覆盖避免重复书写间距。结语Space 是 Formily 表单布局体系中“小而美”的一环它用最小的 API 表面7 个属性覆盖了并排、纵排、对齐、换行与间距继承等日常布局需求同时通过 Void 节点与 Flex 容器的组合与 Formily 的联动、校验、数据模型体系无缝协作。理解它的实现packages/next/src/space/index.tsx与 FormLayout 的 Context 联动机制能帮助你在实际表单项目中更准确地选择布局方案——当需要栅格化的复杂排布时选用FormGrid当只需要紧凑的元素序列时Space 就是最直接的选择。赞分享前端UI组件【免费下载链接】formily Cross Device High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3项目地址https://gitcode.com/gh_mirrors/fo/formily点击查看免费下载相关推荐Formily Next Space 组件完全指南用 Flex 布局快速实现表单元素并排与文本串联Formily Next Space 组件完全指南用 Flex 布局快速实现表单元素并排与文本串联 本文以 formily/next 中的 Space 组件前端UI组件Formily Space 组件实战指南antd 版三种 Schema 模式实现表单元素并排布局Formily Space 组件实战指南antd 版三种 Schema 模式实现表单元素并排布局 Space 是 Formily 在 formily/a前端UI组件formily/antd Space 组件完全指南三种 Schema 写法的 Flex 并排布局实战formily/antd Space 组件完全指南三种 Schema 写法的 Flex 并排布局实战 Space 是 Formily 体系中一个超级便捷的前端UI组件上一篇agent-starter-pack enhance 命令实战指南不新建目录将现有项目原地升级为生产级 Agent下一篇Weaver一款 Swift 语言的依赖注入框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表