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 相关文章推荐
js 对联广告、漂浮广告封装类(IE,FF,Opera,Safari,Chrome
Nov 26 Javascript
浅析JavaScript中的常用算法与函数
Nov 21 Javascript
javascript判断网页是关闭还是刷新
Sep 12 Javascript
win7下安装配置node.js+express开发环境
Dec 06 Javascript
jQuery Easyui学习之datagrid 动态添加、移除editor
Jan 27 Javascript
深入理解JavaScript中的预解析
Jan 04 Javascript
Javascript别踩白块儿(钢琴块儿)小游戏实现代码
Jul 20 Javascript
javascript+html5+css3自定义弹出窗口效果
Oct 26 Javascript
Vue CLI 3搭建vue+vuex最全分析(推荐)
Sep 27 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
Apr 03 Javascript
Angular Excel 导入与导出的实现代码
Apr 17 Javascript
通过实例了解js函数中参数的传递
Jun 15 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
将数字格式的计算结果转为汉字格式
2006/10/09 PHP
php实现window平台的checkdnsrr函数
2015/05/27 PHP
Laravel路由设定和子路由设定实例分析
2016/03/30 PHP
ThinkPHP中where()使用方法详解
2016/04/19 PHP
Windows2003下php5.4安装配置教程(IIS)
2016/06/30 PHP
javascript一些不错的函数脚本代码
2008/09/10 Javascript
javascript 当前日期加(天、周、月、年)
2009/08/09 Javascript
Javascript计算两个marker之间的距离(Google Map V3)
2013/04/26 Javascript
动态的绑定事件addEventListener方法的使用
2014/01/24 Javascript
jquery淡化版banner异步图片文字效果切换图片特效
2014/04/08 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
2015/05/25 Javascript
使用Raygun对Node.js应用进行错误处理的方法
2015/06/23 Javascript
jquery mobile开发常见问题分析
2016/01/21 Javascript
微信小程序 MINA文件结构
2016/10/17 Javascript
Node批量爬取头条视频并保存方法
2018/09/20 Javascript
微信小程序自定义键盘 内部虚拟支付
2018/12/20 Javascript
JS函数基本定义与用法示例
2020/01/15 Javascript
JS eval代码快速解密实例解析
2020/04/23 Javascript
[01:10:58]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第二场 6.2
2018/06/03 DOTA
python数据持久存储 pickle模块的基本使用方法解析
2019/08/30 Python
python 遍历pd.Series的index和value
2019/11/26 Python
关于pytorch中全连接神经网络搭建两种模式详解
2020/01/14 Python
浅谈Keras的Sequential与PyTorch的Sequential的区别
2020/06/17 Python
python 利用zmail库发送邮件
2020/09/11 Python
利用Python pandas对Excel进行合并的方法示例
2020/11/04 Python
python用分数表示矩阵的方法实例
2021/01/11 Python
C#如何调用Windows程序打开一个文档
2014/12/26 面试题
村官工作鉴定评语
2014/01/27 职场文书
大学生个人求职口试自我评价
2014/02/16 职场文书
爱心活动计划书
2014/04/26 职场文书
战略合作意向书
2014/07/29 职场文书
房屋授权无偿使用证明
2014/11/29 职场文书
2015年乡镇环保工作总结
2015/04/22 职场文书
舞蹈社团活动总结
2015/05/07 职场文书
劳动争议仲裁代理词
2015/05/25 职场文书
新手必备之MySQL msi版本下载安装图文详细教程
2021/05/21 MySQL