基于js的表单校验函数validate.js

运行node index.js  依赖lodash

index.js 

var schema = require('./validate');
var user = schema({
    name: {
        name: '用户名',
        type: 'string',
        required: true,
        min_len: 6,
        max_len: 10
    },
    email: {
        name: '邮箱',
        type: 'string',
        required: true,
        email: true
    }
});

var tips = user.validate({name: 'test', email: 'abc'});
if(tips) {
    console.log(tips);
    // tips将提示 ["用户名至少6个字符,当前4个字符","邮箱格式错误"]
}

validate.js

/**
 * @file 数据验证
 * - 数据校验时只校验已存在规则
 * - 数据初始化时转化数据类型
 * */
 'use strict';
 const _ = require('lodash');
 const tips = require('./tips');
 const rules = require('./rules');
 
 /**
  * 检验一个数据是否符合规则
  * @param {any} value 要校验的数值
  * @param {string} ruleName  匹配的规则
  * @param {any} param 规则所带参数,例如最大包含数目的数字
  * @param {string} name  不匹配时提示的名称
  * @returns {false|string} 匹配规则时返回false,否则返回错误提示内容
  */
 function validateOneRules(value, ruleName, param, name, attr) {
     if (rules[ruleName]) {
         var r = rules[ruleName];
         var test = false;
         if (typeof r === 'function') {
             test = r(value, param);
         }
         else if (r instanceof RegExp) {
             test = r.test(value);
         }
 
         if (!test) {
             var tip = tips[ruleName] || tips.def;
             var type = typeof tip;
             if (type === 'string') {
                 var obj = {value: value, param: param, name: name, attr: attr};
                 return tip.replace(/\{(\w+)\}/g, function (all, word) {
                     return obj[word];
                 });
             }
             else if (type === 'function') {
                 return tip(value, param, name, attr);
             }
         }
     }
 
     return false;
 }
 
 function validateRules(value, _rules, attr) {
     var error;
     if (_rules) {
         if (typeof _rules === 'string') {
             _rules = {
                 _rules: true
             };
         }
 
         let required = validateOneRules(value,
             'required',
             _rules.require || _rules.required,
             _rules.name || attr,
             attr);
 
         if (required) {
             return required;
         }
 
         for (var ruleName in _rules) {
             if (ruleName === 'require' || ruleName === 'required') {
                 continue;
             }
 
             error = validateOneRules(value, ruleName, _rules[ruleName], _rules.name || attr, attr);
             if (error) {
                 if(_rules.message){
                     error = _rules.message
                 }
                 return error;
             }
 
         }
     }
 
     return false;
 }
 
 /**
  * 验证obj是否符合schema规则
  * @param {Object} obj     : 要检查的对象
  * @param {Object} schema  : 检查规则
  * @param {boolean} total   : 是否检查所有属性(为false时将只检查obj上存在的属性)
  */
 function validate(obj, schema, total) {
     if (!_.isPlainObject(obj)) {
         throw new Error('validate parameter format error: need plain object!');
     }
 
     total = typeof total === 'undefined' ? true : total;
     var errors = [];
     for (var attr in schema) {
         if (!total && !obj.hasOwnProperty(attr)) {
             continue;
         }
 
         let msg = validateRules(obj[attr], schema[attr], attr);
         if (msg) {
             errors.push(msg);
         }
 
     }
     return errors.length > 0 ? errors : false;
 }
 function create(schemas, options) {
     'use strict';
     if (options) {
         for (var attr in options) {
             addRule(attr, options[attr].test, options[attr].tip);
         }
     }
 
     if (!_.isPlainObject(schemas)) {
         throw new Error('schema need plain object.');
     }
 
     return {
         validate: function (obj, allFields) {
             return validate(obj, schemas, allFields);
         },
         validateAttr: function (value, attr) {
             if (!schemas[attr]) {
                 return false;
             }
 
             return validateRules(value, schemas[attr], attr);
         }
     };
 }
 
 create.tips = tips;
 create.rules = rules;
 create.addRule = function (ruleName, test, tip) {
     if (ruleName && test) {
         rules[ruleName] = test;
         tips[ruleName] = tip;
     }
 
 };
 
 module.exports = create;
 

rules.js

/**
 * @file 校验规则
 */
 function required(value, param) {
    if (param && !value && value !== 0 && value !== false) {
        return false;
    }

    return true;
}

module.exports = {
    min: function (val, param) {
        return parseFloat(val) >= parseFloat(param);
    },
    max: function (val, param) {
        return parseFloat(val) <= parseFloat(param);
    },
    required: required,
    require: required,
    max_len: function (val, param) {
        return (val + '').length <= param;
    },
    min_len: function (val, param) {
        return (val + '').length >= param;
    },
    reg_exp: function (val, param) {
        return param.test(val);
    },
    num: /^\s*\d*\s*$/,
    number: /^\s*[\-\+]{0,1}\d*(\.\d*){0,1}\s*$/,
    float: /^\s*[\-\+]{0,1}\d*(\.\d*){0,1}\s*$/,
    password: /^[\w\.\$\d_\@]*$/,
    email: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)*$/,
    en_text: /^[\w\d_]*$/,
    zh_text: /^[\u4e00-\u9fa5]*$/,
    mobile: /^\d{11}$/,

    // 枚举值
    enum: function (val, param) {
        if (param && param.length > 0) {
            return param.indexOf(val) >= 0;
        }
        return false;
    }
};

tips

/**
 * @file 校验提示, 校验未通过时的错误提示
 */

module.exports = {
    def: '{name}格式错误', // 默认错误提示
    min: '{name}小于最小值{param}',
    max: '{name}超过最大值{param}',
    required: '{name}不能为空',
    require: '{name}不能为空',
    max_len: function (value, param, name) {
        return name + '最多' + param + '个字符,当前' + (value + '').length + '个字符!';
    },
    min_len: function (value, param, name) {
        return name + '最少' + param + '个字符,当前' + (value + '').length + '个字符!';
    },
    num: '{name}必须是纯数字!',
    int: '{name}必须是纯数字!',
    number: '{name}必须是数字!',
    float: '{name}必须是数字!'
};

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值