ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

amis HBox 水平布局组件详解:从 JSON 配置到 Flex 实现原理

amis HBox 水平布局组件详解:从 JSON 配置到 Flex 实现原理 amis HBox 水平布局组件详解从 JSON 配置到 Flex 实现原理【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amisHBox 是 amis 低代码框架内置的水平布局渲染器通过type: hbox一条 JSON 配置即可将多个子渲染器横向排列为等宽或自定义宽度的多列布局。本文以 docs/zh-CN/components/hbox.md 为骨架结合 HBox 渲染器源码、布局样式 与 单元测试完整讲解 HBox 的属性表、列集合写法、间距与对齐控制以及底层 Flex 布局的实现细节。基本用法HBox 使用columns数组描述列集合每个成员可以是普通字符串也可以是任意 SchemaNode 渲染器节点。列成员上通过columnClassName指定该列容器额外的 CSS 类名用于控制宽度、边框、背景等视觉样式。一个典型的双列示例[ { type: hbox, className: b-a bg-dark lter, columns: [ { type: plain, text: Col A, columnClassName: wrapper-xs b-r }, Col B ] }, { type: hbox, className: b-a m-t bg-dark lter, columns: [ { type: plain, text: w-md, columnClassName: w-md wrapper-xs bg-primary b-r }, ... ] } ]要点说明第一组 HBox 展示了两列平均分配的效果columns中第一个成员是带columnClassName的plain文本渲染器第二个成员是纯字符串Col B会被 amis 自动包装渲染第二组 HBox 通过columnClassName: w-md wrapper-xs bg-primary b-r把第一列固定为w-md宽度其余列自动分配剩余空间实现固定列 自适应列的经典布局className作用于 HBox 外层 DOM示例中使用了 amis 内置的边框b-a、背景bg-dark、bg-primary与外边距m-t工具类。混合宽度与等宽分配HBox 的默认行为是所有列等宽分配详见下文 Flex 原理。从 HBox 测试用例 可以看到五种列混排的写法前三列分别通过columnClassName: w-xs、w-sm、w固定宽度后两列不指定宽度自动均分剩余空间。其快照HBox.test.tsx.snap表明渲染出的 DOM 结构为div.cxd-Hbox.cxd-Hbox--xs ├── div.cxd-Hbox-col.w-xs ├── div.cxd-Hbox-col.w-sm ├── div.cxd-Hbox-col.w ├── div.cxd-Hbox-col ← 未指定宽度等宽 └── div.cxd-Hbox-col ← 未指定宽度等宽属性表下表在原文档属性表基础上补充了 AMISHBoxSchema 与 AMISHBoxColumn 类型定义中额外声明的属性属性名类型默认值说明typestringhbox指定为 HBox 渲染器classNamestring外层 Dom 的类名gapxs \| sm \| base \| none \| md \| lgxs水平间距valigntop \| middle \| bottom \| between垂直对齐方式alignleft \| right \| between \| center水平对齐方式columnsArray列集合columns[x]SchemaNode成员可以是其他渲染器columns[x].columnClassNamestringwrapper-xs列上类名columns[x].valigntop \| middle \| bottom \| between当前列内容的垂直对齐columns[x].widthnumber \| string列宽度auto时自适应内容columns[x].heightnumber \| string列高度columns[x].styleobject其他样式直接写入列 DOMcolumns[x].modenormal \| inline \| horizontal列内子表单项默认展示方式columns[x].horizontalFormHorizontal水平排版下左右宽度占比细化columns[x].visibleboolean该列是否显示columns[x].visibleOnAMISExpression是否显示表达式数据驱动subFormModenormal \| inline \| horizontal列内子表单项默认展示方式作用于整个 HBoxsubFormHorizontalFormHorizontal列内水平排版的左右宽度占比作用于整个 HBox说明一gap默认值。原文档未标注默认值但 HBox 的 defaultProps 明确声明gap: xs因此未配置gap时列间默认采用xs档位的水平间距none可彻底取消间距。说明二columns[x]链接。原文档中columns[x]指向 SchemaNode即 amis 的通用节点类型文档位于 docs/zh-CN/types/schemanode.md。源码实现HBox 的渲染流程HBox 渲染器定义在 packages/amis/src/renderers/HBox.tsx核心类HBox通过Renderer({type: hbox})装饰器注册为 amis 渲染器。其渲染流程可以概括为三层外层容器render 方法渲染一个根div类名由Hbox基础类、className、gapHbox--{gap}、valignHbox--v{Valign}、alignHbox--h{Align}组合而成style原样透传列容器renderColumn 方法遍历columns为每列生成一个Hbox-coldiv根据column.width是否为auto、是否有自定义宽度分别附加Hbox-col--auto、Hbox-col--customWidth类名并把width、height、style合并写入行内样式列内容渲染renderChild 方法通过 amis 的render(region, node, props)递归渲染列内的子节点并向子节点传递formMode与formHorizontal优先取列上的column.mode/column.horizontal其次取subFormMode/subFormHorizontal最后回落全局formMode/formHorizontal。值得注意的细节renderColumn中先通过isVisible(column, data)判断列的visible/visibleOn因此可以在 JSON 中按数据条件动态隐藏某一列列内容被渲染为column/${key}区域确保每列拥有独立的渲染作用域。布局原理基于 Flex 的等宽与间距实现HBox 的样式定义在 packages/amis-ui/scss/layout/_hbox.scss全部基于 CSS Flexbox 实现不依赖栅格系统外层.Hbox声明display: flex; flex-direction: row; flex-wrap: nowrap即单行横向排列、不换行默认列.Hbox-col声明flex-basis: 0; flex-grow: 1; width: 100%这正是所有列等宽分配的实现基础——每列可伸缩基数相同剩余空间被均分指定宽度后列会附加Hbox-col--customWidth样式置为flex-grow: unset; flex-basis: unset列宽完全由行内width决定其余列继续均分剩余空间宽度为auto时列附加Hbox-col--auto样式为flex: 0 0 auto; width: auto列宽收缩为内容宽度且不可伸缩。gap的实现方式比较特别外层容器使用负 marginmargin-left/right: calc(var(--gap-*)) * -0.5列内部使用正 paddingpadding-left/right: calc(var(--gap-*)) * 0.5从而在不改变列宽计算的前提下形成均匀的列间距。xs / sm / base / md / lg各档位对应的间距尺寸由主题变量--gap-*定义如--gap-xs: var(--sizes-size-3)见 packages/amis-ui/scss/_properties.scss开发者可通过主题定制统一调整。对齐方式水平 align 与垂直 valignHBox 同时支持水平与垂直两个维度的对齐由源码中类名映射与样式共同完成维度属性取值生成的类名样式效果水平alignleft无附加类默认左对齐justify-content不设置水平alignrightHbox--hRightjustify-content: flex-end水平aligncenterHbox--hCenterjustify-content: center水平alignbetweenHbox--hBetweenjustify-content: space-between垂直valigntop无附加类默认顶部对齐垂直valignmiddleHbox--vMiddle列内flex-direction: column; justify-content: center垂直valignbottomHbox--vBottom列内flex-direction: column; justify-content: flex-end垂直valignbetweenHbox--vBetween列内flex-direction: column; justify-content: space-between类名映射逻辑位于 HBox 的 render 方法垂直对齐通过Hbox--v{ucFirst(valign)}拼装水平对齐通过Hbox--h{ucFirst(align)}拼装。此外单列还可以覆盖整体对齐columns[x].valign会在列容器上生成Hbox-col--v{Valign}类名见 renderColumn对应样式.Hbox .Hbox-col--vTop/vMiddle/vBottom/vBetween只作用于当前列方便实现整体居中对齐、某列底部对齐等混合效果。列条件渲染与表单模式透传除原文档属性表列出的字段外源码还支持两类实用能力列级条件渲染columns[x].visible与columns[x].visibleOnAMISHBoxColumn 定义结合isVisible(column, data)判断可依据页面数据动态显示/隐藏某一列常用于按角色或业务状态切换列展示表单排版模式透传当 HBox 列内嵌套表单项时mode/horizontal列级与subFormMode/subFormHorizontalHBox 级会逐层透传给子渲染器renderColumn 中的传参使 HBox 可以直接作为表单的水平分段容器使用无需在每个表单项上重复声明排版方式。结语HBox 是 amis 中实现横向多列布局的最小成本方案默认等宽、可选固定/自适应宽度、支持两维对齐与数据驱动显隐底层只依赖 Flex 的几条规则性能与可定制性俱佳。其完整类型定义、默认值与渲染逻辑可在 HBox.tsx 中查阅样式细节可在 _hbox.scss 中验证测试用例与渲染快照分别在 HBox.test.tsx 与 HBox.test.tsx.snap。若需要更复杂的栅格响应式布局可参考 amis 的 Grid 等布局组件HBox 适用于简单、确定的多列场景。【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进