不只校验手机号:我的鸿蒙开源校验库,开始处理更复杂的表单场景
做鸿蒙应用时,表单校验看起来是小事:判断一下必填,再检查手机号格式,好像就够了。
但业务稍微复杂一点,就会遇到另一批问题:
- 新建页面要求资料完整,编辑页面却只提交修改的字段,规则要写两份吗?
- 切换个人和企业身份后,必填字段变了,关联错误怎么更新?
- 用户名查重还没返回,用户已经改了输入甚至退出页面,旧任务怎么办?
- 后端给了一份 JSON Schema,里面有当前不支持的规则,能不能明确告诉开发者?
我一直在维护的鸿蒙 ArkTS 开源校验库 @hmkit/validator,最近完成了 1.2.0。这次想分享的,不是一长串 API,而是这些实际场景背后的改进。
发布进度:1.2.0 已提供 GitHub Release,OHPM 发布提交已成功,审核上架状态以 OHPM 页面为准。下文新增能力对应 1.2.0。
先用几行代码认识它
@hmkit/validator 是一个零依赖、纯 ArkTS 实现的声明式表单和数据校验库,采用 MIT 协议开源。
最简单的使用方式,是把分散的判断写成一条规则:
import { v } from '@hmkit/validator';
const result = v.string()
.required('请输入手机号')
.phone()
.validate('13800138000');
// result.valid 为 true
除了单个字段,也可以统一描述一组数据:
import { v } from '@hmkit/validator';
const schema = v.object({
'name': v.string().required('请输入姓名').min(2),
'phone': v.string().required().phone(),
'age': v.number().required().integer().min(18, '需年满 18 岁'),
});
const data: Record<string, Object> = {
'name': '张三',
'phone': '123',
'age': 16,
};
const result = schema.validate(data);
for (const error of result.errors) {
console.error(`${error.path}: ${error.message}`);
}
已有能力还包括中国本地化规则、嵌套对象和数组、跨字段与异步校验、中英文错误消息、字段标签、错误码,以及 ArkUI 表单控制器。
这里也提醒一句:身份证校验位、银行卡 Luhn 等规则属于格式或校验算法检查,不等于实名认证、账户有效性或银行鉴权。
1. 编辑资料,不必重新维护整套规则
新建资料时,我们通常要求字段完整;编辑资料时,可能只更新其中一部分。
如果数据只有一层,可以手动把字段设为可选。但遇到嵌套地址、列表、树形结构,以及不同身份对应不同字段的联合模型,维护成本就会明显增加。
这次我重点完善了 deepPartial():从已有 Schema 派生深层局部更新模型,保留原始模型,扩展到递归 Lazy、组合结构和判别联合等场景。
其中一个容易忽略的细节是判别字段。比如通过 kind 区分个人资料和企业资料,即使允许局部更新,也仍然需要知道本次数据属于哪个分支。新的处理会保留这个检查,缺少或传入未知判别值不会直接放行。
这项能力不是“把所有规则都取消”:
- 字段可省略,不代表可以传
null。 - 业务自定义的 refine / transform 回调不会被自动改写。
- 支持递归 Schema,不等于支持输入对象自身的循环引用。
- 校验局部更新不会自动合并业务数据;合并后仍应使用完整模型再次校验。
我希望它减少规则重复,同时让数据边界保持清楚。
2. JSON Schema 导入,不支持的规则应该看得见
在配置化表单或前后端共享约束的场景中,JSON Schema 很有用。但“能导入”不代表其中每个关键词都被正确执行了。
1.2.0 增加了导入诊断和严格模式。例如,当前还不支持 multipleOf,可以先检查:
import { inspectJSONSchema } from '@hmkit/validator/interop';
const source = JSON.parse(
'{"type":"number","multipleOf":2}'
) as Record<string, Object>;
const diagnostics = inspectJSONSchema(source);
// 诊断会指出 #/multipleOf 当前未支持
导入时可以通过 strict: true 拒绝包含诊断项的 Schema;也可以保持默认宽松模式,通过 onDiagnostic 收集问题。
这一版还补充了布尔 Schema,并修复了 oneOf 分支重叠、组合与同级约束同时存在时的处理,以及部分字符串和数值边界。
需要说清楚:这里的严格模式是当前实现的能力预检,不是完整 JSON Schema 标准合规认证,也不承诺所有文档都能无损往返转换。完整支持范围和限制写在仓库文档里。
3. 异步校验,除了“等结果”,还要能结束任务
远程查重的难点,往往不是发请求,而是如何处理请求的生命周期。
页面退出了,要不要继续等?批量校验几十条数据,是否应该限制并发?某个任务一直没有响应,后面的数据还要继续排队吗?
这次围绕这些问题补充了:
- 异步批量校验的并发上限与超时控制。
- 取消令牌的订阅与退订。
- 自定义字符串、数字异步规则对本次上下文及取消通知的访问。
- 异常、超时与取消路径上的资源清理。
超时会通知本次调用的子令牌,不会直接取消调用者共享的父令牌;父令牌取消时,则可以通知对应调用。
不过,取消通知不会凭空终止底层网络请求。业务适配器仍需要响应通知,调用自己的停止请求方法。页面也需要管理外部任务的令牌,不能只调用 FormValidator.dispose() 就认为所有网络请求都结束了。
仓库里提供了可编译的请求模拟示例,方便先理解这套生命周期,再接入真实网络。
4. 能力继续增加,但入口尽量保持清楚
项目扩展后,我也在关注另一个问题:只需要基础校验的使用者,不应该为了找一个 API,先理解全部高级功能。
目前保留兼容的主入口,同时提供 lite、18 个独立规则子路径,以及这些功能入口:
@hmkit/validator/composition:组合相关能力。@hmkit/validator/interop:Schema 互操作相关能力。@hmkit/validator/execution:执行策略与取消相关能力。@hmkit/validator/form:表单控制器相关能力。
除了使用已有规则,也可以通过自定义同步/异步规则、插件和扩展接口适配业务需求。
这里不做“按需导入就一定缩小多少包体”的承诺:完整 HAR 本次约 146 KiB,随功能增加有所增长。按需入口提供更明确的依赖选择,最终应用包体收益仍需在具体工程中测量。
这次做了哪些验证?
新增功能之外,也修复了嵌套校验上下文丢失、对象覆盖后的可选标记残留,以及表单销毁后仍派发依赖校验等问题。
发布前的本地验证结果是:
- 263 项测试全部通过。
- 行覆盖率 92.83%,函数覆盖率 82.67%,分支覆盖率 83.86%。
- 公共 API、按需入口、包元数据和安全检查通过。
- 主入口与按需入口的独立 HAR 消费工程均构建通过。
模拟器上,两个入口也分别完成了三次进程重启、重复执行、取消状态恢复和退出重进验证。
测试边界同样公开:模拟器首次启动曾出现一次生命周期超时,后续重复测试未复现,根因尚未确定;真机和真实网络场景尚未完成验收。263 项是本地测试数量,不是“263 项真机测试”,覆盖率也不代表没有缺陷。
详细结果保留在验证报告中,方便大家评估是否适合自己的项目。
欢迎试用,也欢迎带着真实场景来提需求
如果你正在做鸿蒙注册登录、资料编辑、嵌套数据校验,或需要把校验规则从页面逻辑里抽出来,可以看看这个项目。
1.2.0 审核上架后,可在项目中安装指定版本:
ohpm install @hmkit/validator@1.2.0
若暂时提示版本不存在,请先查看 OHPM 审核上架状态;也可以从 GitHub Release 获取本次 HAR。
如果觉得有帮助,欢迎 Star。更欢迎带着具体输入、预期结果和最小复现来提 Issue 或 PR。
后续我会继续围绕真实业务完善它:规则能复用,错误能定位,异步任务能管理,扩展时也能保留清晰的边界。
你在鸿蒙开发中遇到过哪些难维护的校验场景?欢迎在评论区聊聊。