在JavaScript开发中,表单验证是保障用户输入合法性的重要环节,传统校验方式往往存在代码冗余、逻辑分散的问题。JS注解作为一种声明式的校验方案,能够将校验规则与业务逻辑解耦,让代码更简洁易维护。

JS注解校验表单的核心原理
JS本身没有原生的注解语法,我们可以通过装饰器或者元数据标记的方式模拟注解效果。核心思路是给需要校验的表单字段添加特定的标记,在提交表单时统一读取这些标记,执行对应的校验逻辑,最后返回校验结果。
常见的实现方式有两种,一种是基于ES6的装饰器语法,另一种是通过给对象属性添加自定义元数据来实现。下面我们以元数据标记的方式为例,讲解完整的实现流程。
自定义基础校验注解
首先我们需要定义几个常用的校验注解,比如非空校验、长度校验、正则格式校验,每个注解对应一个校验函数。
1. 定义注解装饰函数
我们先创建一个工具方法,用来给目标属性添加校验规则元数据:
// 存储所有校验规则的容器
const validationRules = new Map();
/**
* 添加校验规则到目标属性
* @param {Object} target 目标对象
* @param {string} propertyKey 属性名
* @param {Object} rule 校验规则配置
*/
function addValidationRule(target, propertyKey, rule) {
if (!validationRules.has(target)) {
validationRules.set(target, {});
}
const targetRules = validationRules.get(target);
if (!targetRules[propertyKey]) {
targetRules[propertyKey] = [];
}
targetRules[propertyKey].push(rule);
}
/**
* 非空校验注解
* @param {string} message 校验失败提示信息
*/
function NotEmpty(message) {
return function(target, propertyKey) {
addValidationRule(target, propertyKey, {
validator: (value) => {
return value !== undefined && value !== null && value.toString().trim() !== '';
},
message: message || '该字段不能为空'
});
};
}
/**
* 长度范围校验注解
* @param {number} min 最小长度
* @param {number} max 最大长度
* @param {string} message 校验失败提示信息
*/
function Length(min, max, message) {
return function(target, propertyKey) {
addValidationRule(target, propertyKey, {
validator: (value) => {
if (value === undefined || value === null) return false;
const len = value.toString().length;
return len >= min && len <= max;
},
message: message || `长度需要在${min}到${max}之间`
});
};
}
/**
* 正则格式校验注解
* @param {RegExp} pattern 正则规则
* @param {string} message 校验失败提示信息
*/
function Pattern(pattern, message) {
return function(target, propertyKey) {
addValidationRule(target, propertyKey, {
validator: (value) => {
if (value === undefined || value === null) return false;
return pattern.test(value.toString());
},
message: message || '格式不符合要求'
});
};
}
2. 定义表单数据模型
接下来我们创建一个表单数据类,用上面定义的注解标注各个输入参数:
// 手机号正则
const phonePattern = /^1[3-9]d{9}$/;
// 邮箱正则
const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/;
class UserForm {
@NotEmpty('用户名不能为空')
@Length(2, 10, '用户名长度需要在2到10个字符之间')
username = '';
@NotEmpty('手机号不能为空')
@Pattern(phonePattern, '请输入正确的手机号格式')
phone = '';
@Pattern(emailPattern, '请输入正确的邮箱格式')
email = '';
}
实现统一校验器
有了注解规则和标注好的表单模型,我们还需要一个统一的校验器来读取规则并执行校验:
/**
* 表单校验器
* @param {Object} formData 表单数据对象
* @returns {Object} 校验结果,包含是否通过和错误提示
*/
function validateForm(formData) {
const result = {
valid: true,
errors: {}
};
// 获取该表单对象对应的校验规则
const targetRules = validationRules.get(formData.constructor.prototype);
if (!targetRules) {
return result;
}
// 遍历所有需要校验的属性
for (const propertyKey in targetRules) {
const rules = targetRules[propertyKey];
const value = formData[propertyKey];
// 执行每个校验规则
for (const rule of rules) {
if (!rule.validator(value)) {
result.valid = false;
result.errors[propertyKey] = rule.message;
break; // 一个字段只返回第一个错误提示
}
}
}
return result;
}
实际表单校验实践
我们模拟一个表单提交的场景,演示如何使用上面的注解和校验器:
// 模拟表单输入数据
const form = new UserForm();
form.username = '张';
form.phone = '1380013800';
form.email = 'test@ipipp.com';
// 执行校验
const validateResult = validateForm(form);
if (validateResult.valid) {
console.log('表单校验通过,可以提交');
} else {
console.log('表单校验失败:', validateResult.errors);
// 这里可以将错误提示渲染到页面对应表单项下方
}
上面的示例中,手机号长度不足11位,所以校验会失败,返回的错误提示是请输入正确的手机号格式。如果所有字段都符合注解标注的规则,校验结果中的valid会返回true。
注意事项与扩展
- 如果项目支持ES6装饰器,可以直接使用装饰器语法简化注解的写法,上面的示例已经兼容装饰器的写法。
- 可以根据业务需求扩展更多自定义注解,比如数值范围校验、日期格式校验等,只需要新增对应的注解函数即可。
- 校验规则支持嵌套对象的校验,只需要递归读取嵌套属性的校验规则即可实现复杂表单的校验。
- 如果需要在校验时获取更多上下文信息,比如当前表单的其他字段值,可以在校验规则中传入上下文参数,扩展校验函数的入参即可。
通过JS注解的方式实现表单验证,能够让校验规则集中管理,避免在每个表单提交的地方重复编写校验逻辑,后续修改校验规则也只需要调整注解的参数,大大提升了代码的可维护性。
JS注解表单验证输入参数校验JavaScript注解校验修改时间:2026-07-21 16:39:32