Vaadin Flow-一只奇怪的鹿

每一次改变,甚至变得更好,
总是很不方便

理查德·胡克

如您所知,Vaadin是最流行的Java Web框架之一:


最近,已经发布了用于开发Web UI的框架的新版本Vaadin 10,俄文中关于Vaadin 10和Vaadin Flow的出版物很少,这篇文章旨在填补这一空白。


创作者将Vaadin Flow定位为用于开发现代Web应用程序和网站的新Java Web框架(这里我不太相信它们)。 这是Vaadin平台的一部分,该平台替代了另一个产品-Vaadin Framework,它使您可以使用Java Web Components标准来开发Web应用程序(或更确切地说,是Web UI)。

在读者的脑海中,很可能一切都已经被混淆了,所有这些Vaadin Bla Bla,框架,平台等等。 这是怎么回事?

我们已经将Vaadin用作UI后台系统的CUBA平台的一部分,在此期间,我们已经积累了很多与他合作的经验,因此我们不必担心他的命运。 在裁减下,您会发现我在Vaadin 10上的规格。

Vaadin框架


Vaadin是一家芬兰公司,致力于开发用于开发UI的工具和库。 它们使Java的Web开发具有相同的名称。

Vaadin框架是具有服务器端编程模型的UI框架,其中所有UI逻辑及其状态都位于服务器上,并且仅组件的UI代码在浏览器中执行。 实际上,这是一种瘦客户端技术,其中浏览器仅显示服务器所说的内容,所有事件都发送到服务器。

服务器端方法使您无需考虑开发是在Web下进行的,而是将UI开发为可直接访问服务器上的数据和服务的桌面Java应用程序。 同时,Vaadin将负责在浏览器中显示UI以及浏览器与服务器之间的AJAX交互。 Vaadin引擎在浏览器中呈现服务器端应用程序的用户界面,并实现客户端和服务器交换的所有详细信息。



这种方法有很多优点:

  • Java代码更易于编写和调试
  • 您可以使用现有的Java库和工具(IDE,编译器,测试)
  • 无需开发Web服务
  • 安全性更好

缺点:

  • 服务器上需要大量内存才能用于UI视图
  • 难以扩展的解决方案
  • 开发小部件时,您需要开发一个Java API

基于这些优点和缺点,Vaadin FW在企业发展中准确地落定下来,在这里,负载是可以预测的,并且开发速度和便利性比铁和存储器的成本更为重要。

Google Web工具包发生了什么


在Vaadin一直为大众所熟悉的时候,Vaadin FW的客户部分与另一种著名产品Google Web Toolkit(GWT)有着千丝万缕的联系。 这种串联方式使得可以使用一种语言-Java,来编写UI组件本身和用于它们的服务器API,这非常方便。

近年来,Google Web Toolkit尚未开发,自2015年以来,我们都在等待GWT 3.0 / J2CL的出现。


在这个停滞的时期(2015-2017年)发生了一个重要事件:Web组件规范和另一个Google框架Polymer出现了。 显然,这是GWT结束的开始。

值得注意的是,GWT 3正在作为内部Google框架进行开发,其开发是在内部进行的。 因此,社区无法以任何方式影响该过程,或者至少看不到该过程正在进行。

在这种停滞的背景下,Vaadin团队做出了一个艰难的决定,即完全放弃GWT上的开发并改写其框架的客户端部分 。 这些变化不会被忽视,并使已经在Vaadin上进行开发的每个人都感到恐惧。

Web组件


Web组件是一组标准。 它是由Google的人员提出并积极推广的,但是该倡议已经在Mozilla中得到了支持。 本质上,这些是用于为Web创建UI组件的技术,以便它们支持行为和表示的封装。 而且主要优点是可以重用。

关键概念:

  • 自定义元素-用于创建HTML元素的API
  • Shadow DOM是用于封装HTML组件并将其视觉表示与全局CSS规则隔离的工具。 简而言之,您可以制作一个组件(例如订单),而不必担心由于该页面的CSS规则,该样式在网站的某些页面上会损坏。
  • HTML模板-在HTML文档中放置包含DOM空白元素的被动块的功能。 此类块由浏览器解析,但不会呈现或运行其代码。 建议将它们用作数据渲染的模板。
  • HTML导入-能够将HTML文档以其所有布局,样式和JS导入为模块

例如,如果您现在查看YouTube DOM树,则会发现使用“自定义元素”和“影子DOM”:



所有这些使您可以为Web编写新的时尚UI组件。

值得承认的是,浏览器的支持远非完美,仍然需要polyfill ,例如Edge。

高分子


Polymer是Web组件标准之上的一个小型库,旨在简化其使用。 一个例子:

//    import '@polymer/paper-checkbox/paper-checkbox.js'; import {PolymerElement, html} from '@polymer/polymer'; //    class LikeableElement extends PolymerElement { //      static get properties() { return { liked: Boolean }} //    DOM  , CSS      static get template() { return html` <style> .response { margin-top: 10px; } </style> <paper-checkbox checked="{{liked}}">I like web components.</paper-checkbox> <div hidden$="[[!liked]]" class="response">Web components like you, too.</div> `; } } //     customElements.define('likeable-element', LikeableElement); 

实际上,Polymer可以完成GWT之前所做的所有工作,但同时它可以与任何JS组件和其他框架(例如React和Angular)兼容。

Vaadin成分


回到瓦丹。 长期以来,Vaadin一直在开发一种名为Vaadin Components的产品-用于前端开发人员的UI组件,可以将其嵌入任何JS应用程序中。



这些组件基于Web组件和Polymer!

正如我们现在所看到的,这是Vaadin框架的备用机场,它使我们可以离开Goog​​le Web Toolkit并开发一个尚不存在组件的新框架。 鸡肉和鸡蛋问题已经解决,Vaadin组件已成为即将到来的Vaadin 10的前端。

Vaadin流


Vaadin 8包括UI状态同步机制,并支持双向RPC协议(远程过程调用)。 由于GWT,这是可能的,因为服务器和客户端的通用接口和类都是用Java编写的。

与放弃GWT一起,需要实现一种新的机制,该机制允许与JS前端和Java后端进行透明集成。 这种机制就是Vaadin Flow(而且这个名称也早已用于指代整个Vaadin 10)。

Flow 文档具有以下方案:



其主要含义如下:

  • 支持从服务器到客户端的UI状态同步
  • 服务器部分可以订阅UI组件的事件,并且将执行AJAX请求
  • 在服务器上执行业务逻辑,仅将UI中显示的数据加载到Web浏览器中
  • 服务器端使用Java
  • 客户可以使用HTML,CSS,JS和Polymer模板

对我来说,这意味着Vaadin将拥有更多的前端技术,而现在仅Java显然还不够(对于Vaadin 8,Java对您而言就足够了,而HTML / CSS则不是必需的)。 另一方面,现在可以轻松集成JS代码。

Vaadin平台


Vaadin 10的每个组件都是按照JS世界的最佳传统分别开发的,这些微型模块彼此尽可能独立。 同时,组件的客户端部分以WebJARs格式打包在JAR中: www.webjars.org

这有点吓人,尤其是当您查看最小设计时:



为了以某种方式控制这种混乱,出现了一个名为Vaadin Platform的BOM(物料清单)项目。

这不是一些独立的产品,而是以Maven BOM格式设计的组件和工具的兼容版本的列表。

按以下方式连接到Maven:

 <dependencyManagement> <dependencies> <dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin-bom</artifactId> <version>${vaadin.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 

Vaadin 10的功能


总体而言,整个框架包含3个组件:

  1. Vaadin组件-前端
  2. Vaadin Flow-运输
  3. 服务器组件API-用于UI组件的Java API

值得从官方教程开始开发。

另外,我建议参加一个新的网络研讨会

初学者


您可以从该页面更加熟悉该框架。 在那里,您将找到项目示例,包括基于Spring Boot的完整堆栈。

Spring Boot的热心粉丝可以直接进入start.spring.io并从那里的Web框架中选择Vaadin。

一个Java类可以启动一个最小的项目,例如:

 //  URL   @Route("") public class MainView extends VerticalLayout { public MainView() { //  UI   Button button = new Button("Click me"); //    button.addClickListener(event -> { new Notification("Hello!").open(); }); add(button); } } 

通常,您可以在Vaadin 10上书写,就像在Vaadin 8上一样! 您绝对应该查看组件匹配页面

元素API


杀手级功能Vaadin 10-直接从服务器端Java代码控制DOM元素。

 Element nameField = ElementFactory.createInput(); nameField.setAttribute("id", "nameField"); nameField.setAttribute("placeholder", "John Doe"); nameField.setAttribute("autofocus", ""); 

您还可以管理已附加的属性:

 // "John Doe" String placeholder = nameField.getAttribute("placeholder"); // true nameField.hasAttribute("autofocus"); nameField.removeAttribute("autofocus"); // ["id", "placeholder"] nameField.getAttributeNames().toArray(); 

当然,这并不是UI组件的替代品,而是在开发UI组件时不需要简单的布局更改的良好API。

资料绑定


为了与实现HasValue接口的组件(获取/设置值和ValueChangeListener)一起使用,有一个便捷的Binder类:

 Binder<Person> binder = new Binder<>(); TextField titleField = new TextField(); binder.forField(titleField) .bind( Person::getTitle, Person::setTitle); 

从示例中可以看到,支持基于lambda表达式的静态类型的绑定。

此外,活页夹可以安装值转换器和验证器:

 binder.forField(yearOfBirthField) // Validator will be run with the String value of the field .withValidator(text -> text.length() == 4, "Doesn't look like a year") // Converter will only be run for strings with 4 characters .withConverter( new StringToIntegerConverter("Must enter a number")) // Validator will be run with the converted value .withValidator(year -> year >= 1900 && year < 2000, "Person must be born in the 20th century") .bind(Person::getYearOfBirth, Person::setYearOfBirth); 

范本


HTML模板正在排版:

 <link rel="import" href="../bower_components/polymer/polymer-element.html"> <link rel="import" href="../bower_components/paper-input/paper-input.html"> <dom-module id="hello-world"> <template> <div> <paper-input id="inputId" value="{{userInput}}"></paper-input> <button id="helloButton" on-click="sayHello">Say hello</button> <div id="greeting">[[greeting]]</div> </div> </template> <script> class HelloWorld extends Polymer.Element { static get is() { return 'hello-world' } } customElements.define(HelloWorld.is, HelloWorld); </script> </dom-module> 

模板支持声明性数据绑定,您可以编写将在原样浏览器中执行的本机JavaScript。 这使您可以实现部分最简单的UI逻辑,而无需将请求发送到服务器。

大事记


组件事件的处理非常简单

 TextField textField = new TextField(); textField.addChangeListener(e -> System.out.println("Event fired")); 

在这里,您不会注意到与Vaadin 8的区别。

路由选择


应用程序中的导航和路由已成为应有的功能

 @Route("some/path") public class SomePathComponent extends Div { public SomePathComponent() { setText("Hello @Route!"); } } 

视图可以确定它们处理的URL,地址需要哪些参数等等。

组件开发


对于Vaadin 10,您可以通过以下方式开发组件:


这种开发定制组件的简单方法也许是向前迈出的最大一步。 不再需要在GWT上为JS编写包装程序,然后在Vaadin上编写服务器端。

Lumo主题


CSS变量现在代替了SASS,而是用于视觉主题,即 构建项目时不再需要编译CSS:

 <custom-style> <style> html { --lumo-font-family: "Open Sans", sans-serif; } </style> </custom-style> 

Valo主题被新的自定义Lumo主题替换。



使用Vaadin FW 8进行迁移


文档中描述了Vaadin 8的迁移选项: vaadin.com/docs/v10/flow/migration/1-migrating-v8-v10.html

在这里,我有个坏消息:如果您在Vaadin 8上编写了一个庞大的项目,那么切换到Vaadin 10时就需要完全重写它。根本没有迁移路径!

Vaadin 10和Vaadin 8在几个方面相似:

  • 服务器端方法
  • 用于开发UI逻辑的Java
  • 数据绑定的相同方法

最重要的Vaadin 10是从头开始编写的新框架

正如开发人员承诺的那样, Vaadin 8将在2022年之前得到支持,并且可能会出现迁移方法。

结论


我认为用Vaadin Flow编写新的Vaadin网站非常重要,因为它已经成为前端技术的事实上的标准,因为编程语言的成熟度取决于其编译器是否使用相同的语言编写。

我希望现在您可以对Vaadin 10提出意见。总的来说,这是一个很好的框架,并且是未来的巨大储备。 对我来说,这是一个极好的实验培训场,它为构建UI提供了新的思路和方法。

Source: https://habr.com/ru/post/zh-CN416893/


All Articles