WrapPanel 自动换行布局
RenderWrapPanel 会按行排列子节点,当前行空间不足时自动换到下一行。它适合标签、筛选条件、按钮组和可变数量的短项。
API 总览
import { RenderButton, RenderWrapPanel, type WrapAlignment, type WrapCrossAlignment,} from 'ds-ui'
| API | 类型 | 用途 |
|---|---|---|
RenderWrapPanel |
class | 自动换行布局,按可用宽度把短项排成多行。 |
WrapAlignment |
type | 单行和多行整体在主轴上的分布方式。 |
WrapCrossAlignment |
type | 同一行内不同高度子节点的交叉轴对齐方式。 |
最小装配顺序是:创建 RenderWrapPanel({ spacing, runSpacing }),再用 addChild(child) 追加每个标签、chip 或短按钮。
何时使用
- 标签、状态 chip、筛选条件和值域按钮数量不固定。
- 工具按钮需要在窄窗口下自然换行。
- 内容项高度接近,不需要严格列对齐。
何时不要使用
- 表单字段需要稳定列宽和标签对齐。使用 GridPanel 或 EntryGrid。
- 子项数量很大。使用 ListView、TreeView 或虚拟化数据组件。
- 需要每列等宽。使用 AdaptiveGrid 或 GridPanel。
最小示例
const tags = new RenderWrapPanel({ spacing: 6, runSpacing: 6,}) tags.addChild(new RenderButton({ label: '内科' }))tags.addChild(new RenderButton({ label: '外科' }))tags.addChild(new RenderButton({ label: '急诊' }))
spacing 控制同一行内的间距,runSpacing 控制行与行之间的间距。
构造参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
spacing |
number |
主题 itemSpacing |
同一行内子节点之间的水平间距。 |
runSpacing |
number |
主题 itemSpacing |
不同行之间的垂直间距。 |
alignment |
WrapAlignment |
'start' |
每一行内子节点沿主轴的分布方式。 |
runAlignment |
WrapAlignment |
'start' |
所有行在容器高度内的分布方式。 |
crossAxisAlignment |
WrapCrossAlignment |
'start' |
同一行内不同高度子节点的垂直对齐方式。 |
spacing 和 runSpacing 不传时会读取主题布局间距。显式传入后,修改属性会触发重新布局。
对齐方式
alignment:控制单行内子节点的横向分布。runAlignment:控制多行整体在容器高度内的分布。crossAxisAlignment:控制同一行内不同高度子节点的垂直对齐。
可用值包括 start、end、center、spaceBetween、spaceAround、spaceEvenly,交叉轴支持 start、end、center。
属性和方法
| API | 返回值 | 说明 |
|---|---|---|
children |
RenderBox[] |
当前子节点列表。业务代码不应直接改数组。 |
spacing |
number |
读写行内间距,修改后触发布局。 |
runSpacing |
number |
读写行间距,修改后触发布局。 |
alignment |
WrapAlignment |
读写行内分布方式,修改后触发布局。 |
runAlignment |
WrapAlignment |
读写行分布方式,修改后触发布局。 |
crossAxisAlignment |
WrapCrossAlignment |
读写交叉轴对齐方式,修改后触发布局。 |
addChild(child) |
void |
追加子节点并触发布局。 |
clearChildren() |
void |
清空子节点,解除父子关系,并在必要时 detach。 |
布局规则
- 每个子节点先用 loose 约束布局,得到自然尺寸。
- 按当前可用宽度从左到右放置子节点。
- 当前行空间不足时换到下一行。
- 每一行高度取该行子节点最大高度。
- 根据
alignment计算行内 x 坐标,根据crossAxisAlignment计算每个子节点 y 坐标。 - 根据
runAlignment计算每一行在容器高度内的 y 坐标。
当父约束宽度无界时,WrapPanel 不会主动换行,宽度取所有行中的自然宽度。放在滚动内容里时要特别注意这一点。
交互和绘制
WrapPanel 本身不处理鼠标、键盘、选中或焦点。交互由子组件负责。WrapPanel 只负责把子组件排到正确位置,并按子节点顺序绘制。
如果子组件需要 tooltip、省略号、复制或 hover,应在子组件内实现,例如使用 Text、Button 或 Chip。
常见错误
用 WrapPanel 做表单
WrapPanel 会根据窗口宽度改变字段所在行,字段标签和值之间很难保持稳定阅读顺序。表单应使用 GridPanel、EntryGrid 或专门表单组合。
超长子项撑开布局
WrapPanel 不会替子项做省略号。超长文本应由子组件限制宽度,并使用 overflow: 'ellipsis' 或 tooltip。
大量子项卡顿
WrapPanel 布局会遍历所有子节点,适合中小规模短项。几千项标签应改用带虚拟化的数据组件。
使用建议
- 标签和短按钮优先使用 WrapPanel。
- 表单字段不要使用 WrapPanel 做列对齐;需要稳定列宽时使用 GridPanel。
- 超长文本项应在子组件内部做省略号和 tooltip,否则会撑开行宽。
- 大量项目应考虑虚拟化列表,不要把几万项一次性放入 WrapPanel。