Vaadin 24中如何将Grid单元格按钮渲染为链接或文本
Vaadin Grid 按钮样式定制解决方案
问题背景
用户在Vaadin Grid单元格中定义了如下按钮渲染器,需要修改代码实现三类样式需求:
private static Renderer<LogRecord> createStatusRenderer(Grid<LogRecord> grid) { return LitRenderer .<LogRecord> of("<vaadin-button theme=\"${item.style}\" @click=\"${handleClick}\">${item.status}</vaadin-button>") .withProperty("style", r -> r.isFailed() ? "error" : "success") .withProperty("status", ComponentLogRecord::getStatus) .withFunction("handleClick", r -> { if (r.hasMessage()) grid.setDetailsVisible(r, !grid.isDetailsVisible(r)); }); }
需求:
- 错误状态按钮显示为红色链接样式
- 正常状态按钮显示为绿色纯文本
- 错误状态按钮显示为带向下箭头后缀的红色纯文本(需求1的替代方案)
解决方案
1. 错误状态红色链接样式 + 正常状态绿色纯文本
核心逻辑:用tertiary-inline主题移除按钮默认边框/背景,通过自定义样式类控制下划线(需穿透组件内部部件),结合Vaadin内置主题变量设置颜色。
修改后的渲染器代码:
private static Renderer<LogRecord> createStatusRenderer(Grid<LogRecord> grid) { return LitRenderer .<LogRecord> of(""" <vaadin-button theme="tertiary-inline ${item.theme}" class="${item.className}" @click="${handleClick}"> ${item.status} </vaadin-button> """) .withProperty("theme", r -> r.isFailed() ? "error" : "success") .withProperty("className", r -> r.isFailed() ? "link-style" : "") .withProperty("status", ComponentLogRecord::getStatus) .withFunction("handleClick", r -> { if (r.hasMessage()) grid.setDetailsVisible(r, !grid.isDetailsVisible(r)); }); }
添加全局CSS样式(可放在frontend/styles/shared-styles.css中):
/* 链接样式:穿透按钮内部label部件设置下划线 */ .link-style::part(label) { text-decoration: underline; cursor: pointer; } /* 错误状态红色 */ vaadin-button[theme~="error"] { color: var(--lumo-error-color); } /* 正常状态绿色 */ vaadin-button[theme~="success"] { color: var(--lumo-success-color); }
2. 错误状态带向下箭头的红色纯文本
核心逻辑:在错误状态文本后添加Vaadin内置向下箭头图标,仅当记录有详情时显示,保持纯文本外观。
修改后的渲染器代码:
private static Renderer<LogRecord> createStatusRenderer(Grid<LogRecord> grid) { return LitRenderer .<LogRecord> of(""" <vaadin-button theme="tertiary-inline ${item.theme}" @click="${handleClick}"> ${item.status} ${item.hasMessage() ? '<vaadin-icon icon="vaadin:angle-down" style="margin-left: var(--lumo-space-xs);"></vaadin-icon>' : ''} </vaadin-button> """) .withProperty("theme", r -> r.isFailed() ? "error" : "success") .withProperty("status", ComponentLogRecord::getStatus) .withProperty("hasMessage", LogRecord::hasMessage) .withFunction("handleClick", r -> { if (r.hasMessage()) grid.setDetailsVisible(r, !grid.isDetailsVisible(r)); }); }
配套CSS样式:
vaadin-button[theme~="error"] { color: var(--lumo-error-color); cursor: pointer; } vaadin-button[theme~="success"] { color: var(--lumo-success-color); } /* 调整图标大小与间距 */ vaadin-button[theme~="error"] vaadin-icon { width: var(--lumo-icon-size-s); height: var(--lumo-icon-size-s); }
内容的提问来源于stack exchange,提问作者Vadim Lotarev
相关产品推荐
相关产品推荐

