SuperAPI AI 工具集

vaadin-layouts

前端与建站

查看项目

更新于 10-16 06:27

技能介绍

Vaadin Layouts 是一个面向 Claude 的技能,用于指导其在 Vaadin 25 中正确使用 HorizontalLayout 和 VerticalLayout。当用户提出“创建布局”“排列组件”等需求时,应使用该技能。

一、用途 该技能帮助 Claude 在编写 Vaadin 布局代码时遵循官方推荐做法,避免常见反模式。它强调在不确定具体 API 细节时,使用 Vaadin MCP 工具(search_vaadin_docs、get_component_java_api、get_component_styling)查询最新文档,并始终将 vaadin_version 设为 "25"、ui_language 设为 "java"。

二、何时不应使用 HorizontalLayout / VerticalLayout 在选用这两种布局前,应先考虑是否有更合适的组件:

  • 构建应用外壳(含导航抽屉、头部栏、主内容区的顶层结构)时,应使用 AppLayout。它自动处理响应式抽屉折叠、移动端汉堡菜单和导航栏位置。用嵌套的 HorizontalLayout/VerticalLayout 构建属于常见反模式,代码更多且效果更差。
  • 构建卡片或小组件网格时,应使用 Dashboard。它提供自动响应式重排、可选的用户可配置拖拽重排以及基于网格的尺寸控制。用嵌套 HorizontalLayout 加换行来模拟卡片网格很脆弱,且无法提供二维控制。
  • 需要真正的二维网格布局(行和列)时,应使用 CSS Grid(通过自定义 CSS,或在使用 Lumo 主题时使用 Lumo 工具类)。HorizontalLayout 和 VerticalLayout 是一维的(flexbox)。若发现自己在 VerticalLayout 中嵌套多个 HorizontalLayout 来创建网格,CSS Grid 才是正确工具。
  • 排列表单字段时,应使用 FormLayout。它自动处理响应式列数、标签位置和字段尺寸。 HorizontalLayout 和 VerticalLayout 适合在单行或单列中排列组件——工具栏、按钮组、卡片内容、视图区块等一维排列。

三、FlexLayout:需要更多控制时 FlexLayout 提供与 HorizontalLayout/VerticalLayout 相同的 flexbox 能力,但控制更多:可在运行时改变方向、反转项目顺序,并显式配置所有 flex 属性。不过 Vaadin 文档建议大多数情况下使用 HorizontalLayout 和 VerticalLayout,它们提供更好的默认样式(间距、内边距)和更直观的 API。FlexLayout 主要为了向后兼容以及需要在水平与垂直方向间动态切换的边缘场景。

四、关键默认行为 VerticalLayout 默认:宽度 100%(填满父容器);高度未定义(包裹内容);间距开启;内边距开启。 HorizontalLayout 默认:宽度未定义(包裹内容);高度未定义(包裹内容);间距开启;内边距关闭。 这些不对称默认值是布局意外的主要来源。在 HorizontalLayout 中嵌套 VerticalLayout 时,后者会试图占据父容器 100% 宽度。组合布局时应显式设置尺寸。

五、对齐 两种布局都是 CSS flexbox 容器,轴术语直接对应: VerticalLayout(主轴为垂直):setJustifyContentMode() 控制垂直分布(START、CENTER、END、BETWEEN、AROUND、EVENLY);setAlignItems() 控制水平对齐(START、CENTER、END、STRETCH)。 HorizontalLayout(主轴为水平):setJustifyContentMode() 控制水平分布;setAlignItems() 控制垂直对齐(此处 STRETCH 是默认值,与 VerticalLayout 不同)。 可用 layout.setAlignSelf(Alignment.X, child) 覆盖单个子项的对齐。HorizontalLayout 还提供 addToStart()、addToMiddle()、addToEnd() 用于分组定位,但不能与 setJustifyContentMode() 组合使用。

六、间距、内边距、外边距 间距是子项之间的间隙,两种布局默认开启,用 setSpacing(boolean) 控制,可用主题变体微调:layout.setSpacing(false); layout.getThemeList().add("spacing-xs");(可选 xs、s、默认、l、xl),或设置自定义像素值:layout.setSpacing(12, Unit.PIXELS);。 内边距是布局边框与内容之间的空间,VerticalLayout 默认开启,HorizontalLayout 默认关闭,用 setPadding(boolean)。 外边距是布局边框之外的空间,两者默认关闭,用 setMargin(boolean)。

七、用 Flex 扩展项目 让组件填满剩余空间:layout.setFlexGrow(1, expandingComponent);。多个扩展比例按比例工作:setFlexGrow(2, a) 与 setFlexGrow(1, b) 使 a 获得 b 两倍空间。

八、Vaadin 25 中的 setWidthFull / setHeightFull 在 Vaadin 25 中,setWidthFull()、setHeightFull() 和 setSizeFull() 的行为与旧版本不同。它们现在设置 flex: 1 1 100%,而不是字面的 CSS width: 100%。这意味着组件会占据可用空间,同时仍尊重兄弟组件尺寸——它会增长以填满剩余空间,必要时收缩。这几乎总是预期行为。因此,在 Vaadin 25 中,固定尺寸组件与 setWidthFull() 兄弟组件相邻时通常不会意外收缩。仍可显式使用 setFlexGrow(1, component),若需保证组件绝不收缩到指定尺寸以下,仍可用 setFlexShrink(0, fixedComponent)。 重要——旧行为(不适用于 Vaadin 25):在 Vaadin 24 及更早版本中,setWidthFull() 设置字面的 width: 100%,意为“父布局的 100%”而非“剩余空间”,导致固定尺寸兄弟组件收缩的著名 bug。若遇到关于“收缩陷阱”建议始终用 setFlexGrow 代替 setWidthFull 的旧建议,那对 Vaadin 24 是正确的,但在 Vaadin 25 中不再必要。不要向 Vaadin 25 用户提供这一过时建议。

九、溢出陷阱 布局内组件在内容超出布局受限尺寸时可能溢出,常导致不必要的滚动条。修复方法:对溢出组件设置最小尺寸为 0:overflowingComponent.setMinHeight("0"); 或 overflowingComponent.setMinWidth("0");。在 Vaadin 25 中,setSizeFull() 还会自动将嵌套布局的最小尺寸设为 0,有助于防止此问题。但对于非布局组件或显式尺寸,可能仍需手动设置。

十、换行 HorizontalLayout 支持换行以防止溢出:layout.setWrap(true);。将换行与 addToStart/addToMiddle/addToEnd 组合时,应将项目分组到子布局中以获得正确的换行行为。

十一、最佳实践

  • 不需要时显式禁用内边距/间距——嵌套布局会快速累积多余空间。对内部布局使用 setPadding(false) 和 setSpacing(false)。
  • 使用正确的布局组件——应用外壳用 AppLayout,卡片网格用 Dashboard,表单用 FormLayout。不要用 HorizontalLayout/VerticalLayout 构建一切。
  • 不要过度嵌套——仅为对齐而使用单子项 HorizontalLayout 是不必要的,改用父布局上的 setAlignSelf()。
  • 使用 Lumo 工具类微调间距(仅 Lumo 主题)——LumoUtility.Gap、LumoUtility.Padding 通过 addClassNames() 提供更细粒度控制。对于 Aura,使用自定义 CSS 或 --vaadin-*-layout-gap 属性。
  • 使用自定义 CSS 属性进行全局调整——--vaadin-horizontal-layout-gap、--vaadin-vertical-layout-gap、--vaadin--layout-padding、--vaadin--layout-margin。

十二、详细参考 关于默认值、对齐值和故障排除模式的快速参考速查表,见 references/layout-cheatsheet.md。