HarmonyOS鸿蒙Next中怎样实现公共数据校验工具类?
HarmonyOS鸿蒙Next中怎样实现公共数据校验工具类? 开发中需要校验用户输入:
- 表单字段验证
- 数据格式检查
- 业务规则校验
- 统一错误提示
如何查看Linux系统版本信息
1. 使用 lsb_release 命令
lsb_release 命令用于显示LSB(Linux标准基础)和特定版本信息。
lsb_release -a
输出示例:
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
常用选项:
-a:显示所有信息-d:显示描述信息-r:显示版本号-c:显示代号
2. 查看 /etc/os-release 文件
该文件包含操作系统标识数据。
cat /etc/os-release
输出示例:
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
3. 查看 /etc/issue 文件
该文件包含系统登录前的标识信息。
cat /etc/issue
输出示例:
Ubuntu 20.04.3 LTS \n \l
4. 使用 hostnamectl 命令
hostnamectl 命令用于查询和更改系统主机名及相关设置。
hostnamectl
输出示例:
Static hostname: ubuntu-server
Icon name: computer-server
Chassis: server
Machine ID: 1234567890abcdef1234567890abcdef
Boot ID: abcdef1234567890abcdef1234567890
Operating System: Ubuntu 20.04.3 LTS
Kernel: Linux 5.4.0-91-generic
Architecture: x86-64
5. 查看 /proc/version 文件
该文件显示内核版本信息。
cat /proc/version
输出示例:
Linux version 5.4.0-91-generic (buildd@lgw01-amd64-039) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)) #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021
6. 使用 uname 命令
uname 命令用于显示系统信息。
uname -a
输出示例:
Linux ubuntu-server 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
常用选项:
-a:显示所有信息-s:显示内核名称-r:显示内核版本-v:显示内核发布时间-m:显示机器硬件名称-p:显示处理器类型-o:显示操作系统
7. 查看发行版特定文件
不同发行版可能有特定的版本文件:
-
Red Hat/CentOS/Fedora:
cat /etc/redhat-release cat /etc/centos-release cat /etc/fedora-release -
Debian:
cat /etc/debian_version -
Arch Linux:
cat /etc/arch-release
总结
以上方法可以帮助您获取Linux系统的详细版本信息。根据您的具体需求,选择合适的方法来查看系统版本、内核版本和发行版信息。
解决方案
完整校验工具类
/**
* 数据校验工具类
*/
export class Validator {
/**
* 是否为空
*/
static isEmpty(value: string | null | undefined): boolean {
return value === null || value === undefined || value.trim() === '';
}
/**
* 必填校验
*/
static required(value: string, fieldName: string = '此项'): string | null {
if (this.isEmpty(value)) {
return `${fieldName}不能为空`;
}
return null;
}
/**
* 长度校验
*/
static length(value: string, min: number, max: number, fieldName: string = '此项'): string | null {
if (this.isEmpty(value)) {
return null; // 空值由required校验
}
const len = value.trim().length;
if (len < min) {
return `${fieldName}不能少于${min}个字符`;
}
if (len > max) {
return `${fieldName}不能超过${max}个字符`;
}
return null;
}
/**
* 数字范围校验
*/
static range(value: number, min: number, max: number, fieldName: string = '数值'): string | null {
if (value < min || value > max) {
return `${fieldName}必须在${min}-${max}之间`;
}
return null;
}
/**
* 手机号校验
*/
static phone(value: string): string | null {
const pattern = /^1[3-9]\d{9}$/;
if (!pattern.test(value)) {
return '手机号格式不正确';
}
return null;
}
/**
* 邮箱校验
*/
static email(value: string): string | null {
const pattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
if (!pattern.test(value)) {
return '邮箱格式不正确';
}
return null;
}
/**
* 身份证校验
*/
static idCard(value: string): string | null {
const pattern = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
if (!pattern.test(value)) {
return '身份证号格式不正确';
}
return null;
}
/**
* 日期校验(不能晚于今天)
*/
static dateNotFuture(timestamp: number): string | null {
if (timestamp > Date.now()) {
return '日期不能晚于今天';
}
return null;
}
/**
* 日期范围校验
*/
static dateRange(startTime: number, endTime: number): string | null {
if (startTime >= endTime) {
return '开始时间必须早于结束时间';
}
return null;
}
/**
* 组合校验
*/
static validate(value: string, rules: ValidationRule[]): string | null {
for (const rule of rules) {
const error = rule(value);
if (error) {
return error;
}
}
return null;
}
}
// 校验规则类型
type ValidationRule = (value: string) => string | null;
使用示例
/**
* 物品编辑页面
*/
@Component
struct ItemEditPage {
@State itemName: string = '';
@State itemDesc: string = '';
@State expiryDays: number = 30;
@State nameError: string = '';
@State descError: string = '';
@State daysError: string = '';
/**
* 实时校验名称
*/
onNameChange(value: string): void {
this.itemName = value;
// ✅ 组合校验
this.nameError = Validator.validate(value, [
(v) => Validator.required(v, '物品名称'),
(v) => Validator.length(v, 1, 50, '物品名称')
]) || '';
}
/**
* 失焦校验描述
*/
onDescBlur(): void {
this.descError = Validator.length(this.itemDesc, 0, 200, '描述') || '';
}
/**
* 校验天数
*/
onDaysChange(value: number): void {
this.expiryDays = value;
this.daysError = Validator.range(value, 1, 3650, '有效天数') || '';
}
/**
* 提交前完整校验
*/
async onSubmit(): Promise<void> {
// ✅ 校验所有字段
const errors: string[] = [];
const nameErr = Validator.validate(this.itemName, [
(v) => Validator.required(v, '物品名称'),
(v) => Validator.length(v, 1, 50, '物品名称')
]);
if (nameErr) errors.push(nameErr);
const descErr = Validator.length(this.itemDesc, 0, 200, '描述');
if (descErr) errors.push(descErr);
const daysErr = Validator.range(this.expiryDays, 1, 3650, '有效天数');
if (daysErr) errors.push(daysErr);
// ✅ 有错误则提示
if (errors.length > 0) {
promptAction.showToast({
message: errors[0] // 显示第一个错误
});
return;
}
// ✅ 校验通过,保存数据
await this.saveData();
}
build() {
Column({ space: 16 }) {
// 物品名称
Column({ space: 4 }) {
TextInput({ placeholder: '请输入物品名称' })
.onChange((value) => {
this.onNameChange(value);
});
if (this.nameError) {
Text(this.nameError)
.fontSize(12)
.fontColor(Color.Red);
}
}
.alignItems(HorizontalAlign.Start)
// 描述
Column({ space: 4 }) {
TextArea({ placeholder: '请输入描述(可选)' })
.onChange((value) => {
this.itemDesc = value;
})
.onBlur(() => {
this.onDescBlur();
});
if (this.descError) {
Text(this.descError)
.fontSize(12)
.fontColor(Color.Red);
}
}
.alignItems(HorizontalAlign.Start)
// 提交按钮
Button('保存')
.onClick(() => {
this.onSubmit();
});
}
.padding(16)
}
}
高级校验器
/**
* 高级校验器
*/
export class AdvancedValidator {
/**
* 自定义正则校验
*/
static pattern(value: string, regex: RegExp, message: string): string | null {
if (!regex.test(value)) {
return message;
}
return null;
}
/**
* 唯一性校验(异步)
*/
static async unique(value: string, checkFn: (v: string) => Promise<boolean>, fieldName: string): Promise<string | null> {
const exists = await checkFn(value);
if (exists) {
return `${fieldName}已存在`;
}
return null;
}
/**
* 密码强度校验
*/
static passwordStrength(password: string): string | null {
if (password.length < 8) {
return '密码长度不能少于8位';
}
const hasNumber = /\d/.test(password);
const hasLetter = /[a-zA-Z]/.test(password);
const hasSpecial = /[!@#$%^&*()]/.test(password);
if (!hasNumber || !hasLetter) {
return '密码必须包含字母和数字';
}
return null;
}
/**
* 两次密码一致性校验
*/
static passwordMatch(password: string, confirmPassword: string): string | null {
if (password !== confirmPassword) {
return '两次密码不一致';
}
return null;
}
}
// 使用唯一性校验
async function checkNameUnique(): Promise<void> {
const error = await AdvancedValidator.unique(
this.itemName,
async (name) => {
const count = await ItemDao.countByName(name);
return count > 0;
},
'物品名称'
);
if (error) {
this.nameError = error;
}
}
关键要点
1. 校验时机
// ✅ 实时校验(输入时)
.onChange((value) => {
this.validate(value);
})
// ✅ 失焦校验(离开输入框时)
.onBlur(() => {
this.validate();
})
// ✅ 提交校验(点击按钮时)
.onClick(() => {
if (this.validateAll()) {
this.submit();
}
})
2. 错误显示
// ✅ 推荐:字段下方显示错误
Column() {
TextInput();
if (this.error) {
Text(this.error).fontColor(Color.Red);
}
}
// ✅ 推荐:Toast提示
promptAction.showToast({ message: error });
3. 校验规则复用
// ✅ 定义常用规则
const NameRules: ValidationRule[] = [
(v) => Validator.required(v, '名称'),
(v) => Validator.length(v, 1, 50, '名称')
];
const PhoneRules: ValidationRule[] = [
(v) => Validator.required(v, '手机号'),
(v) => Validator.phone(v)
];
// 复用
Validator.validate(name, NameRules);
Validator.validate(phone, PhoneRules);
最佳实践
✅ 提供友好的错误提示 ✅ 实时反馈校验结果 ✅ 组合多个校验规则 ✅ 封装常用校验方法 ✅ 异步校验用户体验
在HarmonyOS Next中,可通过@ohos.data.preferences创建Preferences实例存储校验规则,使用@ohos.util的LruBuffer缓存校验结果。数据校验逻辑推荐使用ArkTS的装饰器@Watch监听数据变化,结合正则表达式进行格式验证。可封装独立工具类,通过export导出validateData函数供调用。
在HarmonyOS Next中,实现一个公共数据校验工具类,可以遵循以下核心思路,利用ArkTS的类型系统和能力来构建:
1. 核心设计:单一职责与链式调用
建议将校验器(Validator)与校验规则(Rule)分离。每个Rule只负责一种校验逻辑,Validator则管理规则链并执行校验。这支持灵活的规则组合与复用。
2. 基础实现步骤
-
定义校验规则接口:
interface ValidationRule { validate(value: any): boolean; getErrorMessage(): string; } -
实现具体规则类: 针对不同的校验类型(如非空、邮箱格式、手机号、数字范围等)创建类并实现
ValidationRule接口。class RequiredRule implements ValidationRule { validate(value: any): boolean { return value !== null && value !== undefined && value.toString().trim() !== ''; } getErrorMessage(): string { return '该字段为必填项'; } } class EmailFormatRule implements ValidationRule { validate(value: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(value); } getErrorMessage(): string { return '邮箱格式不正确'; } } -
构建校验工具类 (Validator): 这个类负责接收待校验的值和规则列表,按顺序执行校验,并收集错误信息。
class Validator { private rules: ValidationRule[] = []; private value: any; constructor(value: any) { this.value = value; } addRule(rule: ValidationRule): Validator { this.rules.push(rule); return this; // 支持链式调用 } validate(): { isValid: boolean; errors: string[] } { const errors: string[] = []; for (const rule of this.rules) { if (!rule.validate(this.value)) { errors.push(rule.getErrorMessage()); } } return { isValid: errors.length === 0, errors: errors }; } }
3. 使用示例
// 在业务逻辑中调用
const userEmail = 'user@example.com';
const result = new Validator(userEmail)
.addRule(new RequiredRule())
.addRule(new EmailFormatRule())
.validate();
if (!result.isValid) {
// 统一处理错误提示,例如使用UI弹窗
console.error('校验失败:', result.errors);
// 此处可将errors传递给UI组件进行展示
}
4. 高级扩展建议
- 异步校验: 对于需要网络请求的校验(如用户名重复性检查),可以设计支持
Promise的异步规则接口。 - 与ArkUI状态绑定: 可以将校验结果与
@State装饰的变量绑定,实现校验错误信息在UI上的实时响应式显示。 - 规则工厂: 对于常用规则组合,可以创建一个“规则工厂”来快速生成预设的规则集,提升代码简洁性。
通过以上方式,你可以构建一个职责清晰、可扩展性强的公共数据校验工具,满足表单验证、数据格式检查等需求,并统一错误处理逻辑。

