Skip to content
本页目录

引用三方 Npm 组件

Fastball 官方已经提供了常见的组件, 但是难免会出现一些特殊场景是没有被支持的, 这里有三种方式来处理.

  • 全部前端开发: 就是整个功能都让专业前端来完成, 回到前后端分离的开发模式, 这样灵活度最高, 但是如果仅仅是一个小的修改就会代价很高, 因为可能要实现官方组件的大部分功能.
  • 前端二开: 即通过打包的方式, 将 Fastball 生成的组件以 NPM 包的方式发布出去, 前端依赖该 package 并且进行一些调整, 比如 override 一部分 props.
  • 字段嵌入三方组件: 直接引入三方组件, 和其他官方组件组合使用, 这也是本文主要描述的方式, 三方组件可以是引用已有的, 也可以让专业前端开发, 这样整体的灵活度就会很高.

整个使用三方组件的过程, 分为三步:

  1. 声明三方 NPM 包依赖
  2. 引入相应组件
  3. 使用相应组件

示例工程中也有引入 AntDesignQRCode 的例子, 效果可以参见在线示例的 引用 AntD 的二维码引用 AntD 的二维码(Hover Popup)

声明三方依赖

方式比较简单, 在 Fastball 配置文件 fastball-config.yml 文件中, 找到或增加 customNpmDependencies, 内部是 Key-Value 形式的声明, 即 NpmPackageName-Version 的形式.

示例代码如下:

yaml
# ...
theme: default
customNpmDependencies:
  # 自定义组件依赖 antd 的 5.1.0 版本
  antd: ^5.1.0
menus:
#  ...

引入相关组件

引入组件的方式也比较简单, 只需要实现 dev.fastball.ui.components.basic.ReferenceComponent 接口, 并且增加注解 @dev.fastball.ui.components.basic.config.ReferenceComponentConfig, 完善信息即可.

示例代码:

java
@UIComponent
@ReferenceComponentConfig(
    // component name
    componentName = "QRCode",
    // npm package name
    npmPackage = "antd",
    // 是否是默认组件
    defaultComponent = false
)
public class AntDesignQRCodeComponent implements ReferenceComponent {}

上述代码对于前端的依赖相当于是:

js
import { QRCode } from 'antd'

// 如果 defaultComponent = true, 则相当于
import QRCode from 'antd'

使用组件

使用组件的方式就跟其他官方组件的引用方式一致了.

比如我们需要弹窗, 就可以直接使用 @Popup, 示例代码:

java
@UIComponent
@RequiredArgsConstructor
public class PopupQRCodeEmployeeTable implements SearchTable<PopupQRCodeEmployeeTable.PopupQRCodeEmployee, UserQuerier> {

    private final EmployeeRepository employeeRepo;

    @Override
    public DataResult<PopupQRCodeEmployee> loadData(UserQuerier querier) {
        Collection<PopupQRCodeEmployee> data = employeeRepo.findByQuerier(querier).stream().map(employee -> {
            PopupQRCodeEmployee qrCodeEmployee = new PopupQRCodeEmployee();
            BeanUtils.copyProperties(employee, qrCodeEmployee);
            return qrCodeEmployee;
        }).collect(Collectors.toList());
        return DataResult.build(data);
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class PopupQRCodeEmployee extends Employee {
        @Field(title = "证件号码, 鼠标移到字段值上", tips = "员工身份证号")
        @Pattern(message = "需要符合身份证校验规则", regexp = "^(\\d{18}|\\d{15}|\\d{17}x)$")
        @NotNull(message = "certificate number can not be null")
        @CopyableColumn
        // 将引入的三方组件直接使用即可
        @Popup(value = @RefComponent(value = AntDesignQRCodeComponent.class, propsKey = "value", currentFieldInput = true), popupType = PopupType.Popover, triggerType = PopupTriggerType.Hover)
        private String certificateNumber;
    }
}

弹窗相关具体可以参见 弹窗

当然我们也可以配合其他机制, 比如展示组件替换, 示例代码:

java
@UIComponent
@RequiredArgsConstructor
public class QRCodeEmployeeTable implements SearchTable<QRCodeEmployeeTable.QRCodeEmployee, UserQuerier> {

    private final EmployeeRepository employeeRepo;

    @Override
    public DataResult<QRCodeEmployee> loadData(UserQuerier querier) {
        Collection<QRCodeEmployee> data = employeeRepo.findByQuerier(querier).stream().map(employee -> {
            QRCodeEmployee qrCodeEmployee = new QRCodeEmployee();
            BeanUtils.copyProperties(employee, qrCodeEmployee);
            return qrCodeEmployee;
        }).collect(Collectors.toList());
        return DataResult.build(data);
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class QRCodeEmployee extends Employee {
        @Field(title = "证件号码, 使用外部组件转化为二维码", tips = "员工身份证号")
        @Pattern(message = "需要符合身份证校验规则", regexp = "^(\\d{18}|\\d{15}|\\d{17}x)$")
        @NotNull(message = "certificate number can not be null")
        @CopyableColumn
        @DisplayComponent(value = @RefComponent(value = AntDesignQRCodeComponent.class, propsKey = "value", currentFieldInput = true))
        private String certificateNumber;
    }
}