JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】


Posted in Javascript onMay 01, 2020

本文实例讲述了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.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript设计模式 接口介绍
Jul 24 Javascript
jquery Mobile入门—多页面切换示例学习
Jan 08 Javascript
JavaScript操纵窗口的方法小结
Jun 28 Javascript
用javascript对一个json数组深度赋值示例
Jul 27 Javascript
AngularJS 中文API参考手册
Jul 28 Javascript
Bootstrap的class样式小结
Dec 01 Javascript
实现一个简单的vue无限加载指令方法
Jan 10 Javascript
JS实现的简单图片切换功能示例【测试可用】
Feb 14 Javascript
vue.js树形组件之删除双击增加分支实例代码
Feb 28 Javascript
Vue精简版风格指南(推荐)
Jan 30 Javascript
微信小程序实现音乐播放器
Nov 20 Javascript
解决Vue使用bus总线时,第一次路由跳转时数据没成功传递问题
Jul 28 Javascript
javascript实现的图片预览和上传功能示例【兼容IE 9】
May 01 #Javascript
jQuery实现的移动端图片缩放功能组件示例
May 01 #jQuery
jQuery实现移动端图片上传预览组件的方法分析
May 01 #jQuery
jQuery实现的上拉刷新功能组件示例
May 01 #jQuery
JS深入学习之数组对象排序操作示例
May 01 #Javascript
vue 输入电话号码自动按3-4-4分割功能的实现代码
Apr 30 #Javascript
浅谈Vue3.0新版API之composition-api入坑指南
Apr 30 #Javascript
You might like
说说PHP的autoLoad自动加载机制
2012/09/27 PHP
php使用递归计算文件夹大小
2014/12/24 PHP
yii2.0实现创建简单widgets示例
2016/07/18 PHP
PHP大文件切割上传功能实例分析
2019/07/01 PHP
Javascript字符串拼接小技巧(推荐)
2016/06/02 Javascript
JS实现显示带倒影的图片横排居中放大展示特效实例【测试可用】
2016/08/23 Javascript
js基本算法:冒泡排序,二分查找的简单实例
2016/10/08 Javascript
jQuery实现点击任意位置弹出层外关闭弹出层效果
2016/10/19 Javascript
Ajax+FormData+javascript实现无刷新表单信息提交
2016/10/24 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
2020/09/11 Javascript
JavaScript实现点击图片换背景
2020/11/20 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
python实现在windows服务中新建进程的方法
2015/06/30 Python
python 判断参数为Nonetype类型或空的实例
2018/10/30 Python
Python文件循环写入行时防止覆盖的解决方法
2018/11/09 Python
python使用tomorrow实现多线程的例子
2019/07/20 Python
python3文件复制、延迟文件复制任务的实现方法
2019/09/02 Python
python爬取Ajax动态加载网页过程解析
2019/09/05 Python
Python爬虫HTPP请求方法有哪些
2020/06/03 Python
英国时尚家具、家居饰品及礼品商店:Graham & Green
2016/09/15 全球购物
纯净、自信、100%的羊绒服装:360Cashmere
2021/02/20 全球购物
中职应届生会计求职信
2013/10/23 职场文书
思想汇报范文
2013/11/04 职场文书
实习教师自我鉴定
2013/12/09 职场文书
高中毕业自我鉴定
2013/12/13 职场文书
手机被没收检讨书
2014/02/22 职场文书
《颐和园》教学反思
2014/02/26 职场文书
气象学专业个人求职信
2014/04/22 职场文书
机械加工与数控专业自荐书
2014/06/04 职场文书
本科应届生自荐信
2014/06/29 职场文书
教师个人自我剖析材料
2014/09/29 职场文书
临时用工协议书范本
2014/10/29 职场文书
如何做好工作总结!
2019/04/10 职场文书
《鲁滨逊漂流记》之六读后感(4篇)
2019/09/29 职场文书