设计模式4 - 策略模式+代理模式实现表单校验

89 阅读1分钟

策略模式+代理模式实现表单校验

当表单项较少时,可以使用if-else来进行判断,进行错误提示,当表单项较多时,通过配置式的表单规则校验则更利于维护与扩展

Html

<div class="form">
    用户名:<input type="text" id="userDom" name="username">
    <span id="showUser"></span>
    密码:<input type="password" name="password" id="psDom">
    <span id="showPs"></span>
    邮箱:<input type="text" name="email" id="emailDom">
    <span id="showEmail"></span>
    <button id="submit">提交</button>
</div>

Validator类的实现

// add 添加校验规则
// (dom, { strategy: maxLength:5, errMsg: '用户名不能为空' })
// start 开始校验并返回真正的校验结果
// extend 可以扩展 (isMail: function () {})

function Validator () {
  this.cache = []
  this.warnDom = []
}

Validator.prototype.strategies = {
  isNoEmpty: function (value, errMsg) {
    if(value === '') {
      return errMsg
    }
    return true
  },
  maxLength: function (value, length, errMsg) {
    if(value !== '' && value.length > length) {
      return errMsg
    }
    return true
  },
  minLength: function (value, length, errMsg) {
    if(value !== '' && value.length < length) {
      return errMsg
    } 
    return true
  },
}

Validator.prototype.add = function (dom, showDom, strategyArr) {
  const self = this
  this.warnDom.push(showDom)
  strategyArr.forEach(function (el) {
    self.cache.push(function () {
      var arr = el.strategy.split(':')
      // ['isNoEmpty'] 或 ['maxLength', 4]
      var type = arr.shift()
      arr.unshift(dom.value)
      arr.push(el.errMsg)
      console.log('type', type, self.strategies)
      // 处理后 ['isNoEmpty', errMsg] 或 ['isMaxLength', '6', errmsg]
      const msg = self.strategies[type].apply(self, arr)
      if(msg !== true) {
        showDom.innerText = msg
      }
      return msg
    })
  })
}

Validator.prototype.start = function () {
  let flag = true
  // 先清空提示的
  this.warnDom.forEach(el => {
    el.innerText = ''
  })
  this.cache.forEach(el => {
    if (el() != true) {
      flag = false
    }
  })
  return flag
}

Validator.prototype.extend = function (config) {
    Object.assign(this.strategies, config)
}

Validator类的使用

const validator = new Validator()
// 扩展邮箱校验
validator.extend({
  isEmail: function (value, errMsg) {
    if(value !== '' && value.indexOf('@') === -1) {
      return errMsg
    }
    return true
  }
})
const ProxyRequest = (function () {
  validator.add(userDom, showUser, [{ strategy: 'maxLength:6', errMsg: '用户名不能超过6位' }, { strategy: 'isNoEmpty', errMsg: '用户名不能为空' }])
  validator.add(psDom, showPs, [{ strategy: 'minLength:6', errMsg: '用户名不能少于6位' }, { strategy: 'isNoEmpty', errMsg: '密码不能为空' }])
  validator.add(emailDom, showEmail, [{ strategy: 'isEmail', errMsg: '邮箱格式不正确' }, { strategy: 'isNoEmpty', errMsg: '邮箱不能为空' }])
  return function () {
    if(validator.start()) {
      Request()
    }
  }
})() 


submit.onclick = () => {
  // console.log(username.value)
  ProxyRequest()
}

人生苦短,我用element-UI