JS表单验证插件:基于策略模式的数据与逻辑分离实现
本文介绍一种基于策略模式的JS表单验证插件实现方案,通过将验证规则(数据层)与业务逻辑(逻辑层)分离,解决传统插件代码结构混乱、扩展性差的问题。文章详细解析了策略模式在表单验证中的应用,展示了如何定义独立的验证算法,并通过插件接口灵活配置验证规则与错误提示,最终实现高内聚、低耦合的可扩展表单验证功能。
本文详细介绍一种JS表单验证插件的实现方法,核心在于实现数据与逻辑的分离操作。
此前曾开发过一款表单验证插件,为何再次进行开发?主要原因在于旧版代码结构较为杂乱。尽管采用了原型继承的方式进行了分层处理,但业务逻辑与数据结构依然混杂,导致插件的可扩展性和灵活性不足。
深入分析表单验证流程,可将其拆解为两个核心环节:验证的数据依据(怎么验证)以及验证的业务处理(如何验证)。前者属于数据层面,后者属于业务逻辑层面。
点击:这里 查看源码
策略模式将对象和规则区分
为了实现算法(数据层)与对象(逻辑层)的解耦,使算法能够独立于使用它的客户端而变化,此处引入策略模式。
什么是策略模式
策略模式定义了一系列算法,将每个算法封装起来,并允许它们相互替换。该模式确保算法的变化不会影响使用它的客户端。
简而言之,策略模式将对象本身与运算规则分离开来。这一设计模式功能强大,其核心思想体现了面向对象编程中的多态性。
关于策略模式的更多定义,参见
接下来,我们将运用策略模式来解决代码分层问题。
理想中的插件调用
在编写具体代码之前,我们期望通过更简洁的方式调用该插件。
// 获取表单form元素
var form = document.getElementById('myForm');
// 创建表单校验实例
var validation = new FormValidator();
// 编写校验配置
validation.add(form.username, 'isEmpty', '用户名不能为空s');
validation.add(form.password, 'minLength: 6', '密码长度不能小于6个字符');
validation.add(form.password2, 'isEqualTo: password', '密码不一致');
validation.add(form.mobile, 'isMobile', '请填写正确的手机号');
// 开始校验,并接收错误信息
$('#submit-btn').click(function() {
var errorMsg = validation.start();
// 如果有错误信息输出,说明校验未通过
if(errorMsg){
console.log(errorMsg);
return false;
}
})
add()方法参数说明
1、 参数1:需要验证的表单项DOM元素,form[name属性] 2、 参数2:验证方法,用冒号分割,冒号后的值为方法的参数(可选) 3、 参数3:错误提示信息
编写验证函数
开始运用策略模式编写代码。第一步,仅编写不涉及业务逻辑的验证函数算法,即数据层。
var VerifyPolicies = {
isEmpty: function(value, errMsg) {
if(value == '') return errMsg;
},
// 最小长度
minLength: function(value, length, errMsg) {
if (value.length < length) return errMsg;
},
// 手机号码
isMobile: function(value, errMsg) {
if(!/^1[34578]\d{9}$/.test(value)) return errMsg;
},
// 是否相等
isEqualTo: function (value, toDom, errMsg) {
var toValue = document.getElementById(toDom).value;
if(value !== toValue) return errMsg;
}
};
编写验证逻辑
function FormValidator(VerifyPolicy) {
this.verifyPolicies = VerifyPolicy ? VerifyPolicy : VerifyPolicies;
// 待执行的验证函数数组
this.validateFn = [];
}
FormValidator.prototype.add = function(dom, rules, errMsg) {
var _this = this;
this.validateFn.push(function() {
var args = [];
var rule = rules.split(':');
var ruleName = rule[0];
var ruleParam = rule[1];
var value = dom.value;
args.push(value);
if(ruleParam) args.push(ruleParam.trim());
args.push(errMsg);
// 这里调用apply只是为了传参,如果支持ES6,也可以这样做:
// return _this.verifyPolicies[ruleName](...args)
return _this.verifyPolicies[ruleName].apply(null, args);
})
};
FormValidator.prototype.start = function() {
var fn = this.validateFn;
for(var i =0, len = fn.length; ; i++) {
var msg = fn[i]();
if(msg) return msg;
}
};
至此,整个表单验证功能已初步完成。在此方法基础上,可以随意添加新的验证方法。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
