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实现简单模态窗口,背景灰显
Nov 14 Javascript
flexigrid 类似ext grid的JS表格代码
Jul 17 Javascript
Web开发者必备的12款超赞jQuery插件
Dec 03 Javascript
intro.js 页面引导简单用法 分享
Aug 06 Javascript
JavaScript实现数字数组按照倒序排列的方法
Apr 06 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
Oct 28 Javascript
AngularJS入门教程之过滤器用法示例
Nov 02 Javascript
实现微信小程序的wxml文件和wxss文件在webstrom的支持
Jun 12 Javascript
详解如何使用router-link对象方式传递参数?
May 02 Javascript
JavaScript动态检测密码强度原理及实现方法详解
Jun 11 Javascript
vue+axios实现post文件下载
Sep 25 Javascript
javascript实现点击星星小游戏
Dec 24 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
CentOS下PHP7的编译安装及MySQL的支持和一些常见问题的解决办法
2015/12/17 PHP
joomla实现注册用户添加新字段的方法
2016/05/05 PHP
PHP安装GeoIP扩展根据IP获取地理位置及计算距离的方法
2016/07/01 PHP
PHP进阶学习之依赖注入与Ioc容器详解
2019/06/19 PHP
jQuery阻止事件冒泡具体实现
2013/10/11 Javascript
AngularJS基础知识笔记之表格
2015/05/10 Javascript
jQuery实现网页顶部固定导航效果代码
2015/12/24 Javascript
jquery自动补齐功能插件flexselect用法示例
2016/08/06 Javascript
JS实现六位字符密码输入器功能
2016/08/19 Javascript
使用jQuery的toggle()方法对HTML标签进行显示、隐藏的方法(示例)
2016/09/01 Javascript
利用yarn实现一个webpack+react种子
2016/10/25 Javascript
JS使用正则表达式找出最长连续子串长度
2017/10/26 Javascript
TypeScript中使用getElementXXX()的示例代码
2019/09/12 Javascript
vue项目引入ts步骤(小结)
2019/10/31 Javascript
vue+element 实现商城主题开发的示例代码
2020/03/26 Javascript
利用PHP实现递归删除链表元素的方法示例
2020/10/23 Javascript
python字符串加密解密的三种方法分享(base64 win32com)
2014/01/19 Python
深入解析Python中的__builtins__内建对象
2016/06/21 Python
详解Python中的相对导入和绝对导入
2017/01/06 Python
Python 类的继承实例详解
2017/03/25 Python
python MySQLdb使用教程详解
2018/03/20 Python
Python 多线程不加锁分块读取文件的方法
2018/12/11 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
2020/02/22 Python
美国快时尚彩妆品牌:Winky Lux(透明花瓣润唇膏)
2018/11/06 全球购物
Luxplus荷兰:以会员价购买美容产品等,独家优惠
2019/08/30 全球购物
介绍一下grep命令的使用
2015/06/12 面试题
亿企通软件测试面试题
2012/04/10 面试题
几道Web/Ajax的面试题
2016/11/05 面试题
中学门卫岗位职责
2013/12/26 职场文书
大学生感恩父母演讲稿
2014/08/28 职场文书
2014入党积极分子破除“四风”思想汇报
2014/09/14 职场文书
公司年会开场白
2015/06/01 职场文书
安全教育日主题班会
2015/08/13 职场文书
css背景和边框标签实例详解
2021/05/21 HTML / CSS
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang
Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)
2022/07/15 Java/Android