校友会小程序开发笔记十五: 小程序前端数据校验体系的设计与实现
微信小程序前端开发框架没有自带的验证功能,虽然有表单的数据控制属性,但是略显简陋,且不成体系,尤其是结合后端很别扭,因此小女子开发校友录小程序的表单验证时候一般有两种方法,一是自己裸写验证规则,但是需要比较扎实的正则表达式基础,一种是自己封装Validate插件进行表单验证,基于以上原因,小女子自己封装了前端数据校验规则一套,并且与云开发后端数据校验的写法和规则一致(云开发后端数据校验体系参见上一篇笔记:))
校友录小程序集中校验路由
function check(data, rules, that) {
let returnData = {};
for (let k in rules) {
let arr = rules[k].split('|');
let desc = '';
// 校友录小程序数据项说明
for (let i = 0; i < arr.length; i++) {
if (arr[i].indexOf('name=') > -1) {
desc = arr[i].replace('name=', '');
break;
}
}
// 校验
let formName = arr[0];
let val = data[formName];
if (val === undefined) val = '';
if (!Array.isArray(val))
val = String(val).trim(); // 前后去校友录小程序空格
returnData[k] = val;
for (let i = 1; i < arr.length; i++) {
let result = '';
let rules = arr[i].split(':');
// 校友录小程序空不校验
if (rules[0] != 'required' && val == '') continue;
switch (rules[0]) {
case 'required':
result = checkRequired(val, desc);
break;
case 'array':
result = checkArray(val, desc);
break;
case 'date':
result = checkDate(val, desc);
break;
case 'time':
result = checkTime(val, desc);
break;
case 'datetime':
result = checkDatimeTime(val, desc);
break;
case 'min':
result = checkMin(val, Number(rules[1]), desc);
break;
case 'max':
result = checkMax(val, Number(rules[1]), desc);
break;
case 'len':
result = checkLen(val, Number(rules[1]), desc);
break;
case 'in':
result = checkIn(val, rules[1], desc);
break;
case 'email':
result = checkEmail(val, desc);
break;
case 'mobile':
result = checkMobile(val, desc);
break;
case 'int':
result = checkInt(val, desc);
break;
case 'id':
result = checkId(val, desc);
break;
case 'letter':
result = checkLetter(val, desc);
break;
case 'letter_num':
result = checkLetterNum(val, desc);
break;
}
if (result) {
wx.showModal({
title: '温馨提示',
content: result,
showCancel: false,
success(res) {
// 校友录小程序自动聚焦
if (that)
that.setData({
[formName + 'Focus']: true
});
}
});
return false;
} else {
if (that) {
// 删除校友录小程序原有的自动聚焦
if (helper.isDefined(that.data[formName + 'Focus'])) {
that.setData({ //TODO delete?
[formName + 'Focus']: false
});
}
}
}
}
}
return returnData;
}
校友录小程序分项数据校验
function checkRequired(value, desc) {
if (value == '')
return desc + '不能为空';
}
/**
* 校验校友录小程序字符长度
* [@param](/user/param) {*} value
* [@param](/user/param) {*} min
* [@param](/user/param) {*} max
*/
function isCheckLen(value, min, max) { //TODO 数字怎么处理
if (!helper.isDefined(value)) return false;
if (typeof (value) != 'string') return false;
if (value.length < min || value.length > max) return false;
return true;
}
/**
* 校验校友录小程序数字大小
* [@param](/user/param) {*} value
* [@param](/user/param) {*} min
* [@param](/user/param) {*} max
*/
function isCheckM(value, min, max) {
if (!helper.isDefined(value)) return false;
if (typeof (value) == 'string' && /^[0-9]+$/.test(value))
value = Number(value);
if (typeof (value) != 'number') return false;
if (value < min || value > max) return false;
return true;
}
function checkMin(value, len, desc) {
if (value.length < len)
return desc + '不能小于' + len + '位';
};
function checkMax(value, len, desc) {
if (value.length > len)
return desc + '不能大于' + len + '位';
};
function checkLen(value, len, desc) {
if (value.length != len)
return desc + '必须为' + len + '位';
};
function checkMobile(value, desc) {
if (value == '') return '';
if (!/(^1[3|5|8][0-9]{9}$)/.test(value))
return desc + '格式不正确';
}
function checkInt(value, desc) {
if (value == '') return '';
if (!/^[0-9]+$/.test(value))
return desc + '必须为数字';
}
function checkLetter(value, desc) {
if (value == '') return;
if (!/^[A-Za-z]+$/.test(value))
return desc + '必须为字母';
}
function checkLetterNum(value, desc) {
if (value == '') return;
if (!/^\w+$/.test(value))
return desc + '必须为字母,数字和下划线';
}
function checkId(value, desc, min = 1, max = 32) {
if (value == '') return;
if (value.length < min || value.length > max) return false;
if (!/^\w+$/.test(value))
return desc + '必须为ID格式';
}
function isCheckId(value, min = 1, max = 32) {
if (!helper.isDefined(value)) return false;
if (typeof (value) != 'string') return false;
if (value.length < min || value.length > max) return false;
if (!/^\w+$/.test(value))
return false;
return true;
}
// 校友录小程序邮箱
function checkEmail(value, desc) {
if (value == '') return;
let hint = desc + '必须为邮箱格式';
let reg = /^[A-Za-z0-9+]+[A-Za-z0-9\.\_\-+]*@([A-Za-z0-9\-]+\.)+[A-Za-z0-9]+$/;
if (!reg.test(value)) return hint;
}
// 校友录小程序短日期,形如 (2008-07-22)
function checkDate(value, desc) {
if (value == '') return;
let hint = '请选择' + desc;
if (value.length != 10) return hint;
let r = value.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/);
if (r == null) return hint;
let d = new Date(r[1], r[3] - 1, r[4]);
let chk = d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4];
if (!chk)
return hint;
}
// 校友录小程序短时间,形如 (13:04:06)
function checkTime(value, desc) {
if (value == '') return;
let hint = desc + '必须为时间格式';
if (value.length != 8) return hint;
let a = value.match(/^(\d{1,2})(:)?(\d{1,2})\2(\d{1,2})$/);
if (a == null) return hint;
if (a[1] > 24 || a[3] > 60 || a[4] > 60) return hint;
}
// 长时间,形如 (2008-07-22 13:04:06)
function checkDatimeTime(value, desc) {
if (value == '') return;
let hint = desc + '必须为完整时间格式';
if (value.length != 19) return hint;
var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
var r = value.match(reg);
if (r == null) return hint;
var d = new Date(r[1], r[3] - 1, r[4], r[5], r[6], r[7]);
let chk = d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4] && d.getHours() == r[5] && d.getMinutes() == r[6] && d.getSeconds() == r[7];
if (!chk) return hint;
}
function checkArray(value, desc) {
if (value == '') return;
if (!Array.isArray(value))
return desc + '填写错误';
}
function checkIn(value, ref, desc) {
if (value == '') return;
let arr = ref.split(',');
if (!arr.includes(value) && !arr.includes(value + ''))
return desc + '填写错误';
}
/**
* 检查校友录小程序枚举类型
* [@param](/user/param) {*} value
* [@param](/user/param) {*} ref 格式 1,2,3
*/
function isCheckIn(value, ref) {
if (!helper.isDefined(value)) return false;
let arr = ref.split(',');
if (!arr.includes(value) && !arr.includes(value + '')) return false; //字符,数字都支持
return true;
}
校友录小程序应用示例
static getFormCheckRules() {
return {
name: 'formName|required|string|min:2|max:20|name=校友姓名',
sex: 'formSex|required|int|len:1|in:1,2|name=性别',
item: 'formItem|required|string|min:2|max:50|name=班级',
birth: 'formBirth|required|date|name=生日',
enroll: 'formEnroll|required|int|len:4|name=入学年份',
grad: 'formGrad|required|int|len:4|name=毕业年份',
city: 'formCity|required|string|min:2|max:50|name=所在城市',
native: 'formNative|required|string|min:2|max:50|name=籍贯',
edu: 'formEdu|required|string|min:2|max:50|name=学历',
trade: 'formTrade|required|string|min:2|max:50|name=当前行业',
workStatus: 'formWorkStatus|required|string|min:2|max:50|name=工作状态',
company: 'formCompany|required|string|min:2|max:50|name=工作单位',
companyDef: 'formCompanyDef|required|string|min:2|max:50|name=单位性质',
companyDuty: 'formCompanyDuty|string|min:2|max:50|name=工作职位',
openSet: 'formOpenSet|required|int|len:1|in:1,8|name=联系方式公开方式',
mobile: 'formMobile|string|min:2|max:50|name=电话',
wechat: 'formWechat|string|min:2|max:50|name=微信',
email: 'formEmail|email|min:2|max:50|name=Email',
qq: 'formQq|string|min:2|max:50|name=QQ',
desc: 'formDesc|string|max:500|name=自我介绍',
resource: 'formResource|string|max:500|name=需求与资源',
}
}
}