Docs

Documentation versions (currently viewingVaadin 24)
Documentation translations (currently viewingChinese)

本页面内容由官方文档 http://vaadin.com/docs 机器翻译而来,可能包含错误、不准确或措辞不当之处。Vaadin 不保证或声明该翻译的准确性、可靠性或时效性。

从早期 Hilla 版本升级

从 Hilla 1.x 或 2.x 升级到最新版本的步骤。

升级到最新版本的 Hilla 是一个非常好的决定。这样可以让您充分利用 Hilla 的所有功能。此页面分为两个主要部分:从 2.x 升级到 24.4.0,其内容将在下一节介绍;以及从 Hilla 1.x 升级到 Hilla 2.0,其内容在后面的主要章节中详细说明。

从 24.6 升级到 24.7

从 24.7 开始,Hilla 在重新生成 TypeScript 文件时不再需要每次都启动 Maven 或 Gradle 进程。因此,也就无法再依赖构建系统配置。

如果您需要使用来自其他包的 endpoint,请确保它们已被实例化为 Spring Bean:Hilla 现在会在应用程序中可用的 Spring Bean 之间搜索带注解的类。

从 2.x 升级到 24.4.0

从 Hilla 2.x 升级到 24.4.0 涉及在项目的各个部分进行若干重要步骤。本指南为您提供详细的操作指导,确保升级过程顺利,涵盖从构建配置到源代码调整的变化。

虽然该过程可能花费一些时间,但将项目升级到 Vaadin 24.4.0 后,您将使用新的 Vaadin Unified Platform,而不只是 Hilla 框架。

Note
构建相关文件的变更
无论您如何构建项目,以下所列的更改对所有 Hilla 项目均适用。不过,当涉及构建相关文件的更改时,您可根据所用构建工具类型,参考 Maven 项目:pom.xml 变更Gradle 项目:配置变更

Maven 项目:pom.xml 变更

如需将 Maven 项目升级到 Vaadin 24.4.0,请按照下述每一步调整 pom.xml 文件。

重命名 hilla.version 属性

将定义框架版本的属性名称从 hilla.version 改为 vaadin.version,并将其值设置为 24.4.x,或您所用的实际版本。此更改确保后续所有依赖都使用正确的版本变量:

Source code
diff
<properties>
-    <hilla.version>2.x</hilla.version>
+    <vaadin.version>24.4.0</vaadin.version>
</properties>

用 Vaadin BOM 替换 Hilla BOM

将 Bill of Materials (BOM) 从 Hilla 更换为 Vaadin,以确保项目使用兼容的 Vaadin 库版本:

Source code
diff
<dependencyManagement>
    <dependencies>
-        <dependency>
-            <groupId>dev.hilla</groupId>
-            <artifactId>hilla-bom</artifactId>
-            <version>${hilla.version}</version>
-            <type>pom</type>
-            <scope>import</scope>
-        </dependency>
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin-bom</artifactId>
+            <version>${vaadin.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+        </dependency>
    </dependencies>
</dependencyManagement>

更新 Hilla 核心依赖

用等效的 Vaadin 库替换核心 Hilla 库依赖,如下所示:

Source code
diff
<dependencies>
-    <dependency>
-        <groupId>dev.hilla</groupId>
-        <artifactId>hilla</artifactId>
-    </dependency>
+    <dependency>
+        <groupId>com.vaadin</groupId>
+        <artifactId>vaadin</artifactId>
+    </dependency>
</dependencies>

更新 Hilla 的 Spring Boot Starter

将 Hilla Spring Boot starter 依赖更新为 Vaadin 的 Spring Boot starter:

Source code
diff
<dependencies>
-    <dependency>
-        <groupId>dev.hilla</groupId>
-        <artifactId>hilla-spring-boot-starter</artifactId>
-    </dependency>
+    <dependency>
+        <groupId>com.vaadin</groupId>
+        <artifactId>vaadin-spring-boot-starter</artifactId>
+    </dependency>
</dependencies>

处理 React-Spring Boot Starter

确保针对 React 的 Spring Boot starter 也做了对应更新:

Source code
diff
<dependencies>
-    <dependency>
-        <groupId>dev.hilla</groupId>
-        <artifactId>hilla-react-spring-boot-starter</artifactId>
-    </dependency>
+    <dependency>
+        <groupId>com.vaadin</groupId>
+        <artifactId>vaadin-spring-boot-starter</artifactId>
+    </dependency>
</dependencies>

替换 Hilla Maven 插件

将 Maven 插件从 Hilla 切换为 Vaadin,以利用 Vaadin 的构建插件能力:

Source code
diff
<build>
    <plugins>
-       <plugin>
-           <groupId>dev.hilla</groupId>
-           <artifactId>hilla-maven-plugin</artifactId>
-       </plugin>
+       <plugin>
+           <groupId>com.vaadin</groupId>
+           <artifactId>vaadin-maven-plugin</artifactId>
+       </plugin>
    </plugins>
</build>
Note
Hilla Maven 插件出现位置
Hilla Maven 插件在 pom.xml 文件中通常会出现多处,请确保所有位置都替换为 Vaadin Maven 插件。

Hilla React 项目

对于专门使用 Hilla React 的项目,部分依赖现在已包含在标准 Vaadin 24.4.0 构件中,可予以移除。

移除 dev.hilla:hilla-react 依赖

由于 Hilla 功能已整合进 Vaadin 核心构件,无需再单独依赖 dev.hilla:hilla-react,应从项目依赖管理中移除以避免冗余和潜在冲突。

Source code
diff
<dependencies>
    <!-- other dependencies -->
-   <dependency>
-       <groupId>dev.hilla</groupId>
-       <artifactId>hilla-react</artifactId>
-   </dependency>
    <!-- other dependencies -->
</dependencies>

请确认更新后所有功能都能正常运行。Vaadin 应原生支持之前 Hilla 特有的全部特性。

Java 源码变更

将 Java 源代码中的包名 dev.hilla 全部替换为 com.vaadin.hilla,例如,在导包语句中:

Source code
diff
- import dev.hilla.BrowserCallable;
- import dev.hilla.Nullable;
- import dev.hilla.crud.CrudRepositoryService;
+ import com.vaadin.hilla.BrowserCallable;
+ import com.vaadin.hilla.Nullable;
+ import com.vaadin.hilla.crud.CrudRepositoryService;

前端源码变更

升级到 Vaadin 24.4.0 时,务必更新 TypeScript 和 TSX 文件中的导入路径,使其符合 Vaadin 提供的新包名。

通用规则是将所有出现的 @hilla/ 替换为 @vaadin/hilla-。但有两个例外:@hilla/form 应替换为 @vaadin/hilla-lit-form@hilla/react-components/…​ 应替换为 '@vaadin/react-components/…​。因此,替换顺序如下:

更新 @hilla/form 模块导入

@hilla/form 改为 @vaadin/hilla-lit-form

Source code
diff
- import { Binder, field } from '@hilla/form';
+ import { Binder, field } from '@vaadin/hilla-lit-form';

更新 @hilla/react-components 模块导入

@hilla/react-components/ 更新为 @vaadin/react-components/,如下所示:

Source code
diff
- import { TextField } from '@hilla/react-components/TextField.js';
+ import { TextField } from '@vaadin/react-components/TextField.js';

更新其它剩余 @hilla/ 出现位置

确保所有用旧命名空间 @hilla/ 的导入语句均更新为 @vaadin/hilla-,如:

Source code
diff
- import { something } from '@hilla/some-module';
+ import { something } from '@vaadin/hilla-some-module';

这也包括未在上述明确列出但属于 Hilla 套件的其它模块。

更新生成路径导入

若您使用过 Hilla CRUD 辅助工具(如 AutoCRUD, AutoGrid, 和 AutoForm),可能还是从旧 Hilla 目录结构导入了生成的路径,需将这些路径更新为新的 Vaadin 包结构:

Source code
diff
- import type FilterUnion from 'Frontend/generated/dev/hilla/crud/filter/FilterUnion.js';
- import type OrFilter from 'Frontend/generated/dev/hilla/crud/filter/OrFilter.js';
+ import type FilterUnion from 'Frontend/generated/com/vaadin/hilla/crud/filter/FilterUnion.js';
+ import type OrFilter from 'Frontend/generated/com/vaadin/hilla/crud/filter/OrFilter.js';

更新认证代码

自 Vaadin 24.4 起,login()logout() 的 Hilla 认证方法,在服务端返回成功结果后会自动刷新页面。对于需要在客户端处理认证成功结果(如获取用户信息并离线存储)的应用,则应改用 onSuccess() 回调,而不要再等待 Promise 结果。

您可以通过在 TypeScript 源码中搜索 login()logout(),检查应用是否依赖认证结果。将依赖成功结果的代码迁移到 onSuccess() 回调中:

Source code
frontend/auth.ts
- import { login as loginImpl, LoginResult, logout as logoutImpl } from '@vaadin/hilla-frontend';
+ import { login as loginImpl, LoginOptions, LoginResult, logout as logoutImpl, LogoutOptions } from '@vaadin/hilla-frontend';
import { appStore } from './stores/app-store';

// ...

/**
 * Login wrapper method that retrieves user information.
 */
export async function login(username: string, password: string, options: LoginOptions = {}): Promise<LoginResult> {
-   const result = await loginImpl(username, password);
-   if (!result.error) {
-     // Get user info from endpoint
-     await appStore.fetchUserInfo();
-   }
-   return result;
+   return await loginImpl(username, password, {
+     ...options,
+     async onSuccess() {
+       // Get user info from endpoint
+       await appStore.fetchUserInfo();
+     },
+   });
}

/**
 * Logout wrapper method that retrieves user information.
 */
export async function logout(options: LogoutOptions = {}) {
-   await logoutImpl();
-   appStore.clearUserInfo();
+   await logoutImpl({
+     ...options,
+     onSuccess() {
+       appStore.clearUserInfo();
+     },
+   });
}

默认情况下,认证后服务器位置将作为跳转目标。

更新登录表单

对于在登录成功后采用自定义导航(比如使用 Lit 登录表单)来跳转页面的应用,应使用 navigate 回调定制默认页面刷新行为。在 Lit 应用中,登录视图应更新为如下:

Source code
frontend/views/login-form.ts
// ...

export class LoginView extends LitElement implements AfterEnterObserver {
  // the url to redirect to after a successful login
  private returnUrl?: string;

-  private onSuccess = (result: LoginResult) => {
-    window.location.href = result.redirectUrl || this.returnUrl || result.defaultUrl || '/';
-  };
-

// ...

  async login(event: CustomEvent): Promise<LoginResult> {
    this.error = false;
    // use the login helper method from auth.ts, which in turn uses
    // Vaadin provided login helper method to obtain the LoginResult
-    const result = await login(event.detail.username, event.detail.password);
+    const result = await login(event.detail.username, event.detail.password, {
+      navigate: (toPath: string) => {
+        // Consider absolute path to be within the application context.
+        const serverUrl = toPath.startsWith('/') ? new URL(`.${toPath}`, document.baseURI) : toPath;
+
+        // If a login redirect was initiated by the client router, this.returnUrl contains the original destination.
+        // Otherwise, use the URL provided by the server.
+        // As we do not know if the target is a resource or a Hilla view or a Flow view, we cannot just use Router.go
+        window.location.replace(this.returnUrl ?? serverUrl);
+      }
+    });
    this.error = result.error;

-    if (!result.error) {
-      this.onSuccess(result);
-    }
-
    return result;
  }
}

如果 Hilla 默认的页面刷新导航足够用,则可以去除登录表单中的自定义导航。例如,使用 React 登录视图的应用可按如下方式更新:

Source code
frontend/views/LoginView.tsx
export default function LoginView() {
  const hasError = useSignal<boolean>(false);

-  if (state.user && url.value) {
-    const path = new URL(url.value, document.baseURI).pathname;
-    return <NavigateAndReload to={path} />;
-  }
-
  return (
    <LoginOverlay
      opened
      error={hasError.value}
      noForgotPassword
      onLogin={async ({ detail: { username, password } }) => {
-        const { defaultUrl, error, redirectUrl } = await login(username, password);
-
-        if (error) {
-          hasError.value = true;
-        } else {
-          url.value = redirectUrl ?? defaultUrl ?? '/';
-        }
+        const { error } = await login(username, password);
+        hasError.value = Boolean(error);
      }}
    />
  );
}

frontend 目录迁移到 src/main

在 Vaadin 24.4.0 中,默认将 frontend 目录放置在 src/main 下。如果您的项目尚未采用该结构,建议将 frontend 目录移动到 src/main 下,以符合新的 Vaadin 规范。这有助于保持一致性并确保未来与 Vaadin 的兼容性。

React 文件路由

Vaadin 24.4.0 自带基于文件系统的路由器,默认用于 React 应用。这意味着 Frontend/views 目录下的 React 组件会被自动扫描,并根据其文件结构生成路由。但如果您的项目在 Frontend 目录下已有 routes.tsx 文件,则不会使用文件系统路由。如果想启用这一新特性,请参阅 File-Based Routing 了解详细信息。

Gradle 项目:配置变更

基于 Gradle 的项目需对多个文件进行更新,以支持新的 Vaadin 24.4.0 平台。请严格按照下列步骤更新 Gradle 配置文件:

重命名 hillaVersion 属性

hillaVersion 属性更新为 vaadinVersion,并设定值为最新版 24.4.x

gradle.properties:

Source code
diff
- hillaVersion=2.x
+ vaadinVersion=24.4.x

别忘了更新 settings.gradlebuild.gradle 里的引用。

替换 build.gradle 中的 Hilla BOM

dependencyManagement 闭包下,将 BOM 从 Hilla 替换为 Vaadin:

Source code
diff
dependencyManagement {
    imports {
-        implementation platform('dev.hilla:hilla-bom:${hillaVersion}')
+        implementation platform('com.vaadin:vaadin-bom:${vaadinVersion}')
    }
}

更新 Hilla 核心依赖

build.gradle 中,将任意 Hilla 核心库依赖替换为 Vaadin 库:

Source code
diff
dependencies {
-    implementation 'dev.hilla:hilla'
+    implementation 'com.vaadin:vaadin'
}

更新 Hilla 的 Spring Boot Starter

将 Hilla Spring Boot starter 依赖替换为 Vaadin 的 Spring Boot starter:

Source code
diff
dependencies {
-    implementation 'dev.hilla:hilla-spring-boot-starter'
+    implementation 'com.vaadin:vaadin-spring-boot-starter'
}

处理 React-Spring Boot Starter

确保针对 React 的 Spring Boot starter 也做了对应更新:

Source code
diff
dependencies {
-    implementation 'dev.hilla:hilla-react-spring-boot-starter'
+    implementation 'com.vaadin:vaadin-spring-boot-starter'
}

替换 Hilla Gradle 插件

将 Gradle 插件从 Hilla 替换为 Vaadin,以利用最新的 Vaadin 构建能力:

Source code
diff
plugins {
-    id 'dev.hilla' version '2.x'
+    id 'com.vaadin' version '24.4.0'
}

Hilla React 项目

对于专门使用 Hilla React 的项目,相关依赖现在已集成进标准 Vaadin 24.4.0 构件,可以去除。

移除 dev.hilla:hilla-react 依赖

由于 Hilla 功能已集成到 Vaadin 核心构件,无需再单独依赖 dev.vaadin:hilla-react,应自项目依赖管理中移除以避免冗余和潜在冲突。

Source code
diff
dependencies {
-    implementation 'dev.hilla:hilla-react'
}

请确认更新后所有功能均正常可用。Vaadin 应原生支持所有原 Hilla 特有的功能。

生产环境构建

生产环境构建时,应使用 vaadin.productionMode,而非旧的 hilla.productionMode 属性:

Source code
terminal
./gradlew -Pvaadin.productionMode build

最终检查

完成上述修改后,请务必彻底测试应用程序,确保所有依赖都已正确链接且功能正常。关注控制台中关于模块导入或路径的警告和错误,并及时解决。

从 Hilla 1.x 升级到 Hilla 2.0

要将 Hilla 1.x 应用迁移到 Hilla 2.0,您需要对应用进行多处更改。Hilla 2 中的大部分重大更改,均由底层 Java 平台依赖的升级引入:

Jakarta EE 10 & Servlet 6

Hilla 2 基于 Servlet 6 规范,与 Jakarta EE 10 兼容。Java 中需将 javax. 改为 jakarta.,以支持验证和部分可空性注解。

Spring Boot 3

Hilla 2 使用最新版本的 Spring Boot 3 和 Spring Framework 6。这会导致与之前 Spring-boot 2 和 Spring Framework 5 相比,基于 Spring 的功能发生重大变化。

Java 17

Hilla 2 需要 Java 17 或更高版本。这是由 Spring 框架和新版应用服务器所要求的。

此外,以下为框架本身的重要变更:

多模块 Endpoints 解析器与生成器

Hilla 2 更换了解析器和生成器,用于生产 endpoints 的 TypeScript 代码。因此,Hilla 应用的 Java endpoint 和实体代码需要做部分适配。hillaEngine 实验性 feature flag 已被移除。

响应式 Endpoints

之前作为实验性功能(hillaPush feature flag)的响应式 endpoint 现已默认启用。

Vaadin 组件 24

Hilla 2 补全了 Vaadin Flow 24 的发布。Vaadin 组件从 24 版起支持使用 ::part() CSS 选择器进行样式调整。新组件在组件内部样式上有所变化。

迁移前准备

在迁移任何应用程序前,需完成如下准备工作,各小节有详细说明。

配置 Node.js

在进行 Hilla 2 迁移前,请安装 Node.js 18 的最新版本。确保 node 可执行文件已添加到 PATH 环境变量。可参考链接:http://nodejs.dev/en/learn/how-to-install-nodejs/[Node.js 安装指南]。

Maven Wrapper

Hilla 2 要求应用中具备 Maven wrapper 脚本,或在运行环境中可用 mvn,用于根据 pom.xml 配置 endpoints 解析器和生成器。

若项目已包含 mvnwmvnw.cmd Maven wrapper 脚本,Hilla 2 会用这些脚本安装并运行 Maven。可访问链接:http://maven.apache.org/wrapper/[Maven Wrapper] 官网下载并了解在项目中安装的说明。

如需在系统环境中安装 Maven,详见链接:http://maven.apache.org/install.html[Apache Maven 安装文档页面]。

Hilla 依赖升级

pom.xml 文件中将 Hilla 版本升级至最新版本,例如:

Source code
pom.xml
<hilla.version>2.0.0</hilla.version>

最新版号信息可见于链接:http://github.com/vaadin/hilla/releases[GitHub Hilla 发布记录]。

Jakarta EE 10 命名空间

您可从 GitHub 下载免费工具实现包名转换:http://github.com/eclipse/transformer[Eclipse Transformer];及 Apache Migration Tool

这些工具能自动将 Java 类导入、MANIFEST、属性文件及其它资源转换为使用 jakarta.* 命名空间,相关说明参见各工具的 README 文件。

最新版 IntelliJ IDEA 也提供 迁移重构 工具,包括 Java EE 到 Jakarta EE 的包名转换功能。

请确保项目中 Jakarta 规范的版本正确。完整规范列表参见:http://jakarta.ee/release/10/[Jakarta EE 10 规范]。

以下为示例:

Source code
pom.xml
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.0.0</version>
</dependency>
<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>2.1.0</version>
</dependency>
<dependency>
    <groupId>jakarta.enterprise</groupId>
    <artifactId>jakarta.enterprise.cdi-api</artifactId>
    <version>4.0.0</version>
</dependency>
<dependency>
    <groupId>jakarta.enterprise.concurrent</groupId>
    <artifactId>jakarta.enterprise.concurrent-api</artifactId>
    <version>3.0.0</version>
</dependency>

Spring 升级说明

Spring Boot 3 与 Spring Framework 6 并未从根本上改变应用开发方式。主要变化在于 Jakarta EE 10 命名空间、受支持产品、Java 版本以及依赖升级和弃用项。

Spring Boot 3 与 Framework 6 使用了新版本的第三方依赖:Hibernate 6、Hibernate Validator 8,servlet 容器,如 Jetty 11、Tomcat 10.1 等。

Spring 提供了以下迁移指引:http://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide[Spring-boot 3.0 专用迁移指南] 和 Spring Framework 6.x 升级指南

完整更改列表参见:http://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes[Spring-boot 3.0 发布说明] 及 Spring Framework 6.x 新特性

以下各小节为基于 Spring 的 Vaadin 应用所需更改的总览。

升级 Spring 到最新版

您需要将 Spring 升级至最新版,包括 starter parent 依赖:

Source code
pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.2</version>
</parent>

弃用项

VaadinWebSecurityConfigurerAdapter 已弃用并移除(Spring 已不再提供 WebSecurityConfigurerAdapter 类)。请改用 VaadinSecurityConfigurer 类,或[deprecated:com.vaadin:vaadin@V24.9]#VaadinWebSecurity 基类#进行安全配置,例如:

Source code
Java
@EnableWebSecurity
@Configuration
@Import(VaadinAwareSecurityContextHolderStrategyConfiguration.class)
public class SecurityConfigurer {

    @Value("${my.app.auth.secret}")
    private String authSecret;

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // Disable creating and using sessions in Spring Security
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Register your login view to the view access checker mechanism
        http.with(VaadinSecurityConfigurer.vaadin(),
                configurer -> configurer.loginView("/login"));

        // Enable stateless authentication
        http.with(new VaadinStatelessSecurityConfigurer<>(),
                cfg -> cfg.withSecretKey().secretKey(
                     new SecretKeySpec(Base64.getDecoder().decode(authSecret), 1
                          JwsAlgorithms.HS256) 2
               ).and().issuer("com.example.application") 3
        );

        return http.build();
    }
}
Java
Java
Java

该示例中,Spring Boot 2.x 使用的 AuthenticationManagerBuilder 已被 UserDetailsService 替代;http.authorizeRequests().antMatchers() 替换为 http.authorizeHttpRequests().requestMatchers()

Java 版本

需使用 Java 17 或更高版本。示例如下:

Source code
XML
<properties>
    <java.version>17</java.version>
    <!-- OR: -->
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
</properties>
XML

Maven 插件

Maven 有多种可用插件,这里说明升级 Hilla 应用至 2.0 相关插件的使用方式。

Hilla Maven 插件

从 Vaadin 24 起,单独的 vaadin-maven-plugin 不再支持生成 Hilla endpoints。请用 hilla-maven-plugin 替换以支持 Hilla endpoints 功能:

Source code
pom.xml
<groupId>com.vaadin.hilla</groupId>
<artifactId>hilla-maven-plugin</artifactId>
<version>${hilla.version}</version>

可用 hilla-maven-plugin 以同样方式调用此前 vaadin-maven-plugin 的目标,主要影响混合应用(既有 Hilla 客户端视图又有 Flow 服务端视图,创建自 Vaadin/Fusion 23 及更早版本)。

第三方插件版本

请确保项目中显式声明的 Maven 插件(如 nexus-staging-maven-plugin)的版本与 Java 17 兼容。例如,nexus-staging-maven-plugin 最低需 1.6.13 版本。

SLF4J 2.0

Hilla 2、Vaadin 24 及 Spring Boot 3 均采用 SLF4J 2.0,它与早期版本有重大变更。详见:http://www.slf4j.org/news.html[SLF4J 发布说明]。

Hilla Endpoint 的变更

@com.vaadin.hilla.Nonnull 等 null 类型注解的行为,已依照 Java 语言规范 修正,主要影响 endpoint 与实体类中的数组:

  • @com.vaadin.hilla.Nonnull String[] 表示 nullable 的数组,但每项为非空。

  • String @com.vaadin.hilla.Nonnull [] 表示非空数组,但每项可为空。

  • @com.vaadin.hilla.Nonnull String @dev.hilla.Nonnull [] 表示非空数组,其各项也非空。

这也影响 TypeScript 生成代码中的可空性。建议在包级别用 @NonNullApi 注解声明可空性。

Vaadin 组件的重大变更

将 Hilla 应用升级到 Hilla 2 可能涉及多个重大变动,详情见下文各小节。

行为与样式

升级后,行为与样式可能发生变化,具体如下,您可按需调整:

  • Badge 默认不再收缩,可用 CSS [theme~="badge"] { flex-shrink:1; } 恢复。

  • Button 默认不再收缩,可用 CSS vaadin-button { flex-shrink:1; } 恢复。

  • Number Field 的默认宽度现与其它文本输入组件一致,想恢复旧宽度可用 CSS vaadin-number-field { width:8em; }

  • Time Picker 不再自动调整到 min/max 范围内的值。

  • HTML H1…​H6 元素的默认上下边距已被移除。可用如下 CSS 恢复:

    Source code
    styles.css
    h1,h2,h3,h4,h5,h6 { margin-top: 1.25em; }
    h1 { margin-bottom: 0.75em; }
    h2, h3, h4 { margin-bottom: 0.5em; }
    h5 { margin-bottom: 0.25em; }

Web Components 的 API

下列变更影响了 Vaadin 组件的客户端 API:

  • vaadin-checkboxvaadin-radio-button 的标签必须通过 label 属性分配,不再支持默认 slot。

  • vaadin-confirm-dialog.cancel.reject 属性分别重命名为 .cancelButtonVisible.rejectButtonVisible

  • vaadin-number-fieldhas-controls 属性重命名为 step-buttons-visible

  • 已移除弃用的 @vaadin/vaadin-(如 @vaadin/vaadin-grid)npm 包。请用新包名 @vaadin/(如 @vaadin/grid)。

  • 已移除弃用的 **Element 旧类别名(如 GridElement),请直接用组件类(如 Grid)。

  • 已移除拼写错误的 vaadin-iconsbussfuncionmegafonepaletetrendind-down

  • 移除了多个组件过时的方法 notifyResizeupdateStyles

  • 文本输入组件的 preventInvalidInput 已移除,推荐使用 setAllowedCharPattern 替代。

  • 移除只读的 theme property,请使用 theme attribute

组件样式自定义

如您对 Vaadin 组件做过样式自定义,请点击展开详情:

许多 Vaadin 组件的内部结构已经被修改,以提升可访问性并在 Hilla 2 中启用新的、简化的样式方法。这些更改可能会影响您为这些组件应用的自定义 CSS。

在从 Vaadin 组件 23(Hilla 1)或更早版本升级时,您可以将所有 CSS 重构为新的样式方法。另一种选择是保持在旧的(基于 Shadow DOM 的)样式方法,只重写影响您应用的选择器。如果需要,也可以同时并行使用这两种方法。

以下说明基于旧的样式方法,这是一种快速升级的方法。新的样式方法在 样式文档 中有详细描述。

Accordion

Accordion 面板的 summary 部分已重构为单独的 vaadin-accordion-heading 自定义元素,并插槽到面板组件中。

Source code
vaadin-accordion-panel.css
[part="summary"] {...}
Source code
vaadin-accordion-panel.css
::slotted(vaadin-accordion-heading) {...}

之前位于 vaadin-accordion-panel 内部的部分现在已经移动到 vaadin-accordion-heading

Source code
vaadin-accordion-panel.css
[part="toggle"] {...}
Source code
vaadin-accordion-heading.css
[part="toggle"] {...}

summary-content 部分已重命名为 content,并现在位于 vaadin-accordion-heading 中:

Source code
vaadin-accordion-panel.css
[part="summary-content"] {...}
Source code
vaadin-accordion-heading.css
[part="content"] {...}

App Layout

drawernavbar 的背景现在在各自的 part 中定义,而不是在 ::before 伪元素中:

Source code
CSS
[part="navar"]::before {
    background: ...;
}
/* and */
[part="drawer"]::before {
    background: ...;
}
Source code
CSS
[part="navbar"] {
    background: ...;
}
/* and */
[part="drawer"] {
    background: ...;
}

navbar 现在定义了 min-height。您可以使用以下方式撤销此更改:

Source code
CSS
[part="navbar"] {
    min-height: 0;
}

当抽屉为 overlay 模式时,现在会显示阴影。可以用如下方法禁用:

Source code
CSS
:host([overlay]) [part="drawer"] {
    box-shadow: none;
}

Avatar Group

Avatar Group 中的单独 Avatar 已经从 shadow DOM 移动到插槽中:

Source code
vaadin-avatar-group.css
[part="avatar"] {...}
Source code
vaadin-avatar-group.css
::slotted(vaadin-avatar) {...}

Context Menu

Context-menu 项目元素 vaadin-context-menu-item 不再继承自 vaadin-item 元素,因此不再继承其样式。为了分别为 context-menu 项进行样式化,请针对 vaadin-context-menu-item,而不是 vaadin-item

CRUD

“新项”按钮已从 CRUD 的 shadow DOM 移动到插槽,并且已移除 new-button 属性:

Source code
vaadin-crud.css
[new-button] {...}
/* or */
vaadin-button {...}
Source code
vaadin-crud.css
::slotted([slot="new-button"])

CRUD Web 组件内部的 Grid 已经从 CRUD 的 shadow DOM 移动到插槽中。

Date Picker

Date Picker 下拉层中的按钮从 shadow DOM 移动到了插槽:

Source code
vaadin-date-picker-overlay-content.css
[part="today-button"] {...}
/* and */
[part="cancel-button"] {...}
Source code
vaadin-date-picker-overlay-content.css
::slotted([slot="today-button"]) {...}
/* and */
::slotted([slot="cancel-button"]) {...}
/* or target both with */
::slotted(vaadin-button) {...}

日历中的日期元胞可以有多个 part 名称以反映其状态,因此 part 属性选择器必须使用 ~= 运算符以匹配单独的词:

Source code
vaadin-month-calendar.css
[part="date"] {...}
Source code
vaadin-month-calendar.css
[part~="date"] {...}

日期元胞的状态属性已被 part 名称所取代:

Source code
vaadin-month-calendar.css
[part="date"][disabled] {...}
[part="date"][focused] {...}
[part="date"][selected] {...}
[part="date"][today] {...}
Source code
vaadin-month-calendar.css
[part~="date"][part~="disabled"] {...}
[part~="date"][part~="focused"] {...}
[part~="date"][part~="selected"] {...}
[part~="date"][part~="today"] {...}

Details

summary 部分已被重构为单独的自定义元素,并插槽到 Details 组件中:

Source code
vaadin-details.css
[part="summary"] {...}
Source code
vaadin-details.css
::slotted(vaadin-details-summary) {...}

toggle 部分现在在新的 vaadin-details-summary 元素中:

Source code
vaadin-details.css
[part="toggle"] {...}
Source code
vaadin-details-summary.css
[part="toggle"] {...}

summary-content 部分现在在 vaadin-details-summary 元素中,并重命名为 content

Source code
vaadin-details.css
[part="summary-content"] {...}
Source code
vaadin-details-summary.css
[part="content"] {...}

Login

“忘记密码”按钮已从 shadow DOM 移动到插槽:

Source code
vaadin-login-form-wrapper.css
#forgotPasswordButton {...}
/* or */
vaadin-button[theme~="forgot-password"] {...}
/* or */
vaadin-button {...}
Source code
vaadin-login-form-wrapper.css
::slotted([slot="forgot-password"]) {...}

menu-bar 按钮(也是顶级菜单项)已从 shadow DOM 移动到插槽:

Source code
vaadin-menu-bar.css
[part="menu-bar-button"] {...}
/* or */
vaadin-menu-bar-button {...}
Source code
vaadin-menu-bar.css
::slotted(vaadin-menu-bar-button) {...}

Menu Bar 下拉菜单中的项现在是 vaadin-menu-bar-item 而不是 vaadin-context-menu-item,因此不继承 Context Menu 项目的样式。

Message Input

文本区域和按钮已从 shadow DOM 移动到插槽,并替换为常规 Text Area 和 Button 实例:

Source code
vaadin-message-input.css
vaadin-message-input-text-area {...}
/* and */
vaadin-message-input-button {...}
Source code
vaadin-message-input.css
::slotted(vaadin-text-area) {...}
/* and */
::slotted(vaadin-button) {...}

Message List

列表中的消息元素已从 shadow DOM 移动到插槽中:

Source code
vaadin-message-list.css
vaadin-message {...}
Source code
vaadin-message-list.css
::slotted(vaadin-message) {...}

消息中的头像已被移动到自己的插槽,并替换为常规的 vaadin-avatar 实例:

Source code
vaadin-message.css
[part="avatar"] {...}
/* or */
vaadin-message-avatar {...}
Source code
vaadin-message.css
::slotted(vaadin-avatar) {...}

Multi-Select Combo Box

芯片元素以及溢出芯片已从 shadow DOM 移动到插槽:

Source code
vaadin-multi-select-combo-box.css
vaadin-multi-select-combo-box-chip {...}
[part~="chip"] {...}
[part~="overflow"] {...}
[part~="overflow"][part~="overflow-one"] {...}
Source code
vaadin-multi-select-combo-box.css
::slotted(vaadin-multi-select-combo-box-chip) {...}
::slotted([slot="chip"]) {...}
::slotted([slot="overflow"]) {...}
::slotted([slot="overflow"][count="1"]) {...}

Upload

文件列表已经被重构为其自身的 vaadin-upload-file-list 自定义元素,并插槽到 Upload 组件中:

Source code
vaadin-upload.css
[part="file-list"] {...}
Source code
vaadin-upload.css
::slotted(vaadin-upload-file-list) {...}

上传按钮已从 shadow DOM 移动到插槽:

Source code
vaadin-upload.css
[part="upload-button"] {...}
/* or */
#uploadButton {...}
/* or */
vaadin-button {...}
Source code
vaadin-upload.css
::slotted(vaadin-button) {...}

拖放标签和图标已从 shadow DOM 移动到插槽,并且图标现为 vaadin-upload-icon 元素:

Source code
vaadin-upload.css
#dropLabel {...}
/* and */
[part="drop-label-icon"] {...}
Source code
vaadin-upload.css
::slotted([slot="drop-label"]) {...}
/* and */
::slotted(vaadin-upload-icon) {...}