美文网首页让前端飞前端杂记
用策略模式写一个表单验证

用策略模式写一个表单验证

作者: 会飞小超人 | 来源:发表于2018-12-10 11:51 被阅读2次

    首先创建一个基本的表单

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
      
      <form id="registerForm">
          请输入用户名:<input type="text" name="userName"/>
          请输入密码:<input type="text" name="password"/>
          请输入手机号码:<input type="text" name="phoneNumber"/>
          <button>提交</button>
      </form>
    
      <script src="./validator.js"></script>
    </body>
    </html>
    

    普通写法

    validator.js

     var registerForm = document.getElementById('registerForm');
    registerForm.onsubmit = function () {
      if (registerForm.userName.value === '') {
        alert('用户名不能为空');
        return false;
      }
    
      if (registerForm.password.value.length < 6) {
        alert('密码长度不能少于6位');
        return false;
      }
      if (!/(^1[3|5|8][0-9]{9}$)/.test(registerForm.phoneNumber.value)) {
        alert('手机号码格式不正确');
        return false;
      }
    }
    

    策略模式

    const strategies = {
      isNonEmpty: function (value, errorMsg) {
        if (value === '') {
          return errorMsg
        }
      },
      minLength: function (value, length, errorMsg) {
        if (value.length < length) {
          return errorMsg
        }
      },
      isMobile: function (value, errorMsg) {
        if (!/(^1[3|5|8][0-9]{9}$)/.test(value)) {
          return errorMsg
        }
      }
    }
    
    const Validator = function () {
      this.cache = []
    }
    
    Validator.prototype.add = function (dom, rule, errorMsg) {
      let arr = rule.split(':')
      this.cache.push(function () {
        let strategy = arr.shift()
        arr.unshift(dom.value)
        arr.push(errorMsg)
        return strategies[strategy].apply(dom, arr)
      })
    }
    
    Validator.prototype.start = function () {
      for (let i = 0, validatorFunc; validatorFunc = this.cache[i++];) {
        let msg = validatorFunc()
        if (msg) {
          return msg
        }
      }
    }
    
    const validateFunc = function () {
      let validator = new Validator()
    
      /* 添加校验规则 */
      validator.add(registerForm.userName,'isNonEmpty','用户名不能为空')
      validator.add(registerForm.userName,'minLength:6','用户名长度不能少于6位')
      validator.add(registerForm.password,'minLength:6','密码长度不能少于6位')
      validator.add(registerForm.phoneNumber,'isMobile','手机号码格式不正确')
    
      let errorMsg = validator.start()
      return errorMsg
    }
    
    let registerForm = document.getElementById('registerForm')
    registerForm.onsubmit = function () {
      let errorMsg = validateFunc()
      if (errorMsg) {
        console.log(errorMsg)
        return false
      }
    }
    

    如果同一个表单要添加多个校验规则的话,只能重新写一行代码,不够优雅,可以改写add函数,变成配置的形式添加rule,下面是优化版。

    优化版

    /* 其他代码一样,这里只写出改变的代码*/
    
    Validator.prototype.add = function (dom, rules) {
      let self = this
    
      for (var i = 0, rule; rule = rules[i++];) {
        (function (rule) {
          let strategyArr = rule.strategy.split(':')
          let errorMsg = rule.errorMsg
    
          self.cache.push(function () {
            let strategy = strategyArr.shift()
            strategyArr.unshift(dom.value)
            strategyArr.push(errorMsg)
            return strategies[strategy].apply(dom, strategyArr)
          })
        })(rule)
      }
    }
    
    const validateFunc = function () {
      let validator = new Validator()
    
      /* 添加校验规则 */
      // validator.add(registerForm.userName,'isNonEmpty','用户名不能为空')
      // validator.add(registerForm.userName,'minLength:6','用户名长度不能少于6位')
      // validator.add(registerForm.password,'minLength:6','密码长度不能少于6位')
      // validator.add(registerForm.phoneNumber,'isMobile','手机号码格式不正确')
    
      /* 改进版 */
      validator.add(registerForm.userName, [{
        strategy: 'isNonEmpty',
        errorMsg: '用户名不能为空'
      }, {
        strategy: 'minLength:10',
        errorMsg: '用户名长度不能小于10位'
      }]);
    
      validator.add(registerForm.password, [{
        strategy: 'minLength:6',
        errorMsg: '密码长度不能小于6位'
      }]);
    
      validator.add(registerForm.phoneNumber, [{
        strategy: 'isMobile',
        errorMsg: '手机号码格式不正确'
      }]);
    
      let errorMsg = validator.start()
      return errorMsg
    }
    

    相关文章

      网友评论

        本文标题:用策略模式写一个表单验证

        本文链接:https://www.haomeiwen.com/subject/gylacqtx.html