Vaadin 14 Designer设置VerticalLayout宽度被Java引用忽略问题
Vaadin 14 @Id绑定垂直布局导致宽度设置失效问题
在Vaadin 14版本中使用Vaadin Designer创建垂直布局并设置固定宽度(例如3%),同时在对应Java代码中持有该垂直布局组件的引用时,Vaadin会忽略预设的宽度设置。如果不在Java代码中引用该垂直布局,该异常不会出现。
当前临时规避方案有两种:
- 避免在Java代码中持有该布局对象的引用
- 若必须引用,在Java代码中显式重新设置宽度属性
复现代码
前端Polymer组件模板(ui-testview.js)
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js'; import '@vaadin/vaadin-ordered-layout/src/vaadin-horizontal-layout.js'; class UiTestview extends PolymerElement { static get template() { return html` <style include="shared-styles"> :host { display: block; height: 100%; } </style> <vaadin-horizontal-layout class="content" style="width: 100%; height: 100%;"> <vaadin-vertical-layout id="left" style="width: 3%;background-color:blue"> <label>left label</label> </vaadin-vertical-layout> <label style="flex-grow: 1;background-color:red">Label</label> </vaadin-horizontal-layout> `; } static get is() { return 'ui-testview'; } static get properties() { return { // Declare your properties here. }; } } customElements.define(UiTestview.is, UiTestview);
对应Java逻辑代码
package org.vaadin; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.template.Id; import com.vaadin.flow.router.Route; import com.vaadin.flow.templatemodel.TemplateModel; import com.vaadin.flow.component.Tag; import com.vaadin.flow.component.dependency.JsModule; import com.vaadin.flow.component.polymertemplate.PolymerTemplate; /** * A Designer generated component for the ui-testview template. * * Designer will add and remove fields with @Id mappings but * does not overwrite or otherwise change this file. */ @Route("testview") @Tag("ui-testview") @JsModule("./src/ui-testview.js") public class UiTestview extends PolymerTemplate<UiTestview.UiTestviewModel> { @Id("left") private VerticalLayout left; /** * Creates a new UiTestview. */ public UiTestview() { } /** * This model binds properties between UiTestview and ui-testview */ public interface UiTestviewModel extends TemplateModel { // Add setters and getters for template properties here. } }
问题根因
当使用@Id注解把模板里的元素绑定到服务端的VerticalLayout实例时,Vaadin会自动把服务端组件的默认尺寸属性(VerticalLayout默认宽度、高度均为undefined,即自适应内容宽度)同步到前端,这个同步操作会覆盖模板里写的内联style宽度设置。如果没有用@Id绑定服务端组件,就不会触发这个属性同步逻辑,所以模板里的宽度能正常生效。
可行解决方案
- 直接在Java构造方法中,组件绑定完成后显式设置宽度:在
UiTestview构造器里加一行left.setWidth("3%");,这是成本最低、最稳定的方案 - 把宽度样式从元素内联style移到CSS类或者组件的
<style>块中,通过CSS选择器设置#left { width: 3%; },外部/内部CSS的样式优先级不会被服务端同步的内联默认样式覆盖 - 若仅需要持有引用不需要调用VerticalLayout特有的API,可以把字段类型改为通用的
Component,就不会触发VerticalLayout专属的默认尺寸属性同步,不过后续调用布局相关方法需要强转,实用性不高
内容的提问来源于stack exchange,提问作者Jonathan Sylvester
相关产品推荐
相关产品推荐

