引用三方 Npm 组件
Fastball 官方已经提供了常见的组件, 但是难免会出现一些特殊场景是没有被支持的, 这里有三种方式来处理.
- 全部前端开发: 就是整个功能都让专业前端来完成, 回到前后端分离的开发模式, 这样灵活度最高, 但是如果仅仅是一个小的修改就会代价很高, 因为可能要实现官方组件的大部分功能.
- 前端二开: 即通过打包的方式, 将 Fastball 生成的组件以
NPM
包的方式发布出去, 前端依赖该package
并且进行一些调整, 比如override
一部分props
. - 字段嵌入三方组件: 直接引入三方组件, 和其他官方组件组合使用, 这也是本文主要描述的方式, 三方组件可以是引用已有的, 也可以让专业前端开发, 这样整体的灵活度就会很高.
整个使用三方组件的过程, 分为三步:
- 声明三方 NPM 包依赖
- 引入相应组件
- 使用相应组件
示例工程中也有引入 AntDesign
的 QRCode
的例子, 效果可以参见在线示例的 引用 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;
}
}