集成 JavaScript 库
可以基于第三方 JavaScript 库创建自定义的 UI 组件。本节中的示例演示了如何集成 jQuery UI Slider。
创建 JavaScript Web 组件
在 frontend/src/component/slider 内创建如下 slider.js 文件,其中带有包装 jQuery UI Slider 小部件的 Web 组件。ready() 方法用于初始化小部件。
slider.js
import 'jquery/jquery.js'
import 'jquery-ui/dist/jquery-ui.js'
import {LitElement} from 'lit';
import {ElementMixin} from '@vaadin/component-base/src/element-mixin.js';
import {defineCustomElement} from '@vaadin/component-base/src/define.js';
import {PolylitMixin} from '@vaadin/component-base/src/polylit-mixin.js';
export class Slider extends ElementMixin(PolylitMixin(LitElement)) { (1)
static get is() {
return 'demo-slider'; (2)
}
static get properties() { (3)
return {
min: {
type: Number,
value: 0,
observer: '_onMinChange' (4)
},
max: {
type: Number,
value: 100,
observer: '_onMaxChange'
},
value: {
type: Number,
notify: true,
observer: '_onValueChange'
},
/** @private */
_slider: {
type: Object
}
}
}
createRenderRoot() {
return this;
}
ready() {
super.ready();
let $jQuery = jQuery.noConflict();
this._slider = $jQuery(this); (5)
this._slider.slider({ (6)
min: this.min,
max: this.max,
change: function (event, ui) {
if (this.value === ui.value) {
return;
}
this.value = ui.value;
const slideChangeEvent = new CustomEvent(
'custom-slide-changed',
{detail: {value: ui.value}}
);
this.dispatchEvent(slideChangeEvent); (7)
}
});
}
/**
* @protected
*/
_onValueChange(value) { (8)
if (this._slider === undefined) {
return;
}
this._slider.slider("value", value);
}
/**
* @protected
*/
_onMinChange(value) {
if (this._slider === undefined) {
return;
}
this._slider.slider("option", "min", value);
}
/**
* @protected
*/
_onMaxChange(value) {
if (this._slider === undefined) {
return;
}
this._slider.slider("option", "max", value);
}
}
defineCustomElement(Slider); (9)
| 1 | 定义自定义组件的基类。 |
| 2 | 定义 HTML 元素的名称。 |
| 3 | 自定义属性。 |
| 4 | 定义属性更改的监听器。 |
| 5 | 获取根元素的链接。 |
| 6 | 在根元素初始化 jQuery UI Slider。 |
| 7 | 发送 custom-slide-changed 名称的自定义事件。 |
| 8 | 当属性改变时,为 slider 设置新值。 |
| 9 | 使用在 static get is() 方法中定义的名称导出自定义 HTML 元素。 |
为 Web 组件创建 Java API
创建 Slider.java 文件,这是一个 UI 组件类。为服务端代码、访问方法、事件监听器和数据源连接定义了 API。
import com.vaadin.flow.component.*;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;
import com.vaadin.flow.shared.Registration;
@Tag("demo-slider") (1)
@NpmPackage(value = "jquery", version = "1.9.1") (2)
@NpmPackage(value = "jquery-ui", version = "1.13.2")
@CssImport("jquery-ui/dist/themes/base/jquery-ui.css")
@JsModule("./src/component/slider/slider.js") (3)
public class Slider extends Component implements HasSize {
public static final String VALUE_PROPERTY = "value";
public static final String MIN_PROPERTY = "min";
public static final String MAX_PROPERTY = "max";
public static final String SLIDE_CHANGED_EVENT = "custom-slide-changed";
public Slider() {
}
public int getMin() {
return getElement().getProperty(MIN_PROPERTY, 0);
}
public void setMin(int min) {
getElement().setProperty(MIN_PROPERTY, min);
}
public int getMax() {
return getElement().getProperty(MAX_PROPERTY, 100);
}
public void setMax(int max) {
getElement().setProperty(MAX_PROPERTY, max);
}
@Synchronize(property = VALUE_PROPERTY, value = SLIDE_CHANGED_EVENT) (4)
public int getValue() {
return getElement().getProperty(VALUE_PROPERTY, 0);
}
public void setValue(int value) {
getElement().setProperty(VALUE_PROPERTY, value);
}
}
| 1 | 定义由 Component` 类自动创建的 根 元素,可以通过 getElement() 方法访问。必须与 Web 组件导出的相同。 |
| 2 | @NpmPackage 注解定义依赖的 npm 包,其中包含一个或多个 JS 模块。 |
| 3 | @JsModule 注解定义需要导入 JavaScript 模块。 |
| 4 | 为 getter 添加 @Synchronize 注解,告诉 Flow 需要在触发 custom-slide-changed 事件时同步该属性。在本示例中,当滑块的值变化时就会触发该事件。 |
在客户端处理事件
可以将组件事件与浏览器中元素触发的 DOM 事件相关联。为此,需在事件类上使用 @DomEvent 注释来指定要监听的 DOM 事件的名称。如果存在组件事件的监听器,Vaadin Flow 将自动为元素添加 DOM 事件的监听器。
事件可以包含其他附加信息,例如在单击事件中使用的鼠标键。@DomEvent 构造函数支持额外的参数。可以使用 @EventData 指定需要从浏览器发送的数据。
public Registration addValueChangeListener(ComponentEventListener<SlideChangedEvent> listener) {
return addListener(SlideChangedEvent.class, listener);
}
@DomEvent(SLIDE_CHANGED_EVENT) (1)
public static class SlideChangedEvent extends ComponentEvent<Slider> {
protected int value;
public SlideChangedEvent(Slider source, boolean fromClient,
@EventData("event.detail.value") int value) { (2)
super(source, fromClient);
this.value = value;
}
public int getValue() {
return value;
}
}
| 1 | 使用 @DomEvent 注解将 Slider 组件与 custom-slide-changed DOM 事件相关联 |
| 2 | 使用 @EventData 注解定义附加的事件数据,本例中为 slider 的值。 |
| 关于创建自定义组件的更多内容可以参阅 Vaadin 文档: 导入 JavaScript & CSS, 集成 Web 组件, Element API |
用例
组件实现完成后,可以在视图 XML 和 Java 中使用,示例:
XML 中使用
<view xmlns="http://jmix.io/schema/flowui/view"
xmlns:app="http://company.com/schema/app-ui-components"> (1)
<layout>
<app:slider id="slider"
width="20em"
min="10" max="100" value="50"/> (2)
</layout>
</view>
| 1 | 用与组件 XSD 中相同的 xmlns 和 targetNamespace 属性定义命名空间。 |
| 2 | 添加 slider 元素时,需使用 app 命名空间前缀。 |
编程式用法
@Autowired
protected Notifications notifications;
@Subscribe
public void onInit(final InitEvent event) {
Slider slider = new Slider();
slider.setWidth("20em");
slider.setMin(10);
slider.setMax(100);
slider.setValue(50);
slider.addValueChangeListener(changedEvent ->
notifications.create("New value is : " + changedEvent.getValue())
.withPosition(Notification.Position.MIDDLE)
.show());
getContent().add(slider);
}
本页是否有帮助?
感谢您的反馈