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最新动画教程+iso光盘下载
Jan 22 Javascript
Three.js源码阅读笔记(Object3D类)
Dec 27 Javascript
javascript中Date format(js日期格式化)方法小结
Dec 17 Javascript
js实现的二分查找算法实例
Jan 21 Javascript
详解Bootstrap插件
Apr 25 Javascript
Bootstrap Table 在指定列中添加下拉框控件并获取所选值
Jul 31 Javascript
parabola.js抛物线与加入购物车效果的示例代码
Oct 25 Javascript
微信小程序tabBar模板用法实例分析【附demo源码下载】
Nov 28 Javascript
基于vue cli 通过命令行传参实现多环境配置
Jul 12 Javascript
详解使用React制作一个模态框
Mar 14 Javascript
详解vue.js移动端配置flexible.js及注意事项
Apr 10 Javascript
Vue请求java服务端并返回数据代码实例
Nov 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防注
2007/01/15 PHP
PHP字符串比较函数strcmp()和strcasecmp()使用总结
2014/11/19 PHP
javascript 避免闭包引发的问题
2009/03/17 Javascript
学习ExtJS TextField常用方法
2009/10/07 Javascript
javascript 仿QQ滑动菜单效果代码
2010/09/03 Javascript
jQuery实现切换页面布局使用介绍
2011/10/09 Javascript
javascript级联下拉列表实例代码(自写)
2013/05/10 Javascript
JS模拟Dialog弹出浮动框效果代码
2015/10/16 Javascript
JavaScript学习笔记之数组随机排序
2016/03/23 Javascript
Angular 理解module和injector,即依赖注入
2016/09/07 Javascript
Node.js的环境安装配置(使用nvm方式)
2016/10/11 Javascript
node.js发送邮件email的方法详解
2017/01/06 Javascript
js实现密码强度检验
2017/01/15 Javascript
Nodejs回调加超时限制两种实现方法
2017/06/09 NodeJs
完美解决axios跨域请求出错的问题
2018/02/05 Javascript
JavaScript字符串转数字的5种方法及遇到的坑
2018/07/16 Javascript
jQuery实现的模仿雨滴下落动画效果
2018/12/11 jQuery
Node.js爬虫如何获取天气和每日问候详解
2019/08/26 Javascript
layer实现登录弹框,登录成功后关闭弹框并调用父窗口的例子
2019/09/11 Javascript
解决python爬虫中有中文的url问题
2018/05/11 Python
nohup后台启动Python脚本,log不刷新的解决方法
2019/01/14 Python
Python3.5基础之函数的定义与使用实例详解【参数、作用域、递归、重载等】
2019/04/26 Python
python使用pymongo与MongoDB基本交互操作示例
2020/04/09 Python
Python自定义sorted排序实现方法详解
2020/09/18 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
2021/03/03 Python
CSS3教程(8):CSS3透明度指南
2009/04/02 HTML / CSS
德国2018年度最佳在线药房:Bodfeld Apotheke
2019/11/04 全球购物
公关关系专员的自我评价分享
2013/11/20 职场文书
学生干部的自我评价分享
2014/01/18 职场文书
学校校庆演讲稿
2014/05/22 职场文书
2014年生产部工作总结
2014/12/17 职场文书
单位政审意见范文
2015/06/04 职场文书
干部外出学习心得体会
2016/01/18 职场文书
村党总支部公开承诺书2016
2016/03/25 职场文书
简单聊聊Golang中defer预计算参数
2022/03/25 Golang
搭建zabbix监控以及邮件报警的超级详细教学
2022/07/15 Servers