You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:24:22