表单校验之策略模式

好比单例模式用的最多的就是遮罩层的、全局dialog这种,那么表单校验这块最经典就是策略模式了。

即便是在 vuejs 开发的项目中,你只需要校验变量这么简单的操作,但是有了策略模式代码的组织结构将会更好,每个人在业务代码中不再需要自己定义一套业务规则。

这里我使用ES6的类来定义 Validator 本质上也是也函数,但类的方式,子类扩展的话会更加直观。

//validator.js

'use strict';

let strategies = {
  isNonEmpty: (value, errorMsg) => {
    if (value === '') {
      return errorMsg;
    }
  },
  maxLength: (value, length, errorMsg) => {
    if (value > length) {
      return errorMsg;
    }
  },
};

class Validator {
  constructor() {
    this.cache = [];
  }

  add(data, rules) {
    var self = this;
    rules.forEach((item, index) => {
      (function(rule) {
        var strategyArr = rule.strategy.split(':');
        var errorMsg = rule.errorMsg;
        self.cache.push(() => {
          var strategy = strategyArr.shift(); //取出校验名称
          strategyArr.unshift(data); //放入待校验值
          strategyArr.push(errorMsg);
          return strategies[strategy].apply(data, strategyArr);
        });
      })(item);
    });
  }

  start() {
    for (var i = 0, validatorFunc; validatorFunc = this.cache[i++];) {
      var errorMsg = validatorFunc();
      if (errorMsg) {
        return errorMsg;
      }
    }
  }
}

export default Validator;

业务层直接引入 Validator 类。

import Validator from '../../util/validate';

validateExpressForm() {
    let validator = new Validator();
    validator.add(this.userSoNo, [
        {
        strategy: 'isNonEmpty',
        errorMsg: '快递单号不能为空',
        }]);
    validator.add(this.paymentFee, [
        {
        strategy: 'isNonEmpty',
        errorMsg: '补偿费用不能为空',
        }]);
    var errorMsg = validator.start();
    return errorMsg;
}