You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.5 KiB

import AsyncValidator from 'async-validator'
const utils = {
validate: (model, rules, callback, options) => {
const initOptions = {
showMessage: true
}
options = Object.assign({}, initOptions, options || {})
let promise = null;
if (typeof callback !== 'function') {
promise = new Promise((resolve, reject) => {
callback = function(valid) {
valid ? resolve(valid) : reject(valid)
}
})
}
// 如果需要验证的fields为空,调用验证时立刻返回callback
if (!rules || (Array.isArray(rules) && rules.length === 0) || (typeof rules === 'object' && Object.keys(rules).length ===
0)) {
callback(true, null);
if(promise){
return promise
}
return
}
let errors = []
const props = Object.keys(rules)
let count = 0
for (let i in props) {
const prop = props[i]
const value = utils.getValueByProp(model, prop)
utils.validateItem(rules, prop, value, (err) => {
if (err && err.length > 0) {
errors = errors.concat(err)
}
// 处理异步校验,等所有校验都结束时再callback
count++
if (count === props.length) {
if (errors.length > 0) {
if (options.showMessage) {
utils.showToast(errors[0].message)
}
callback(false, errors)
} else {
callback(true, null)
}
}
})
}
if (promise) {
return promise
}
},
validateField: (model, rules, props, callback, options) => {
const initOptions = {
showMessage: true
}
options = Object.assign({}, initOptions, options || {})
let promise = null;
if (typeof callback !== 'function') {
promise = new Promise((resolve, reject) => {
callback = function(valid) {
valid ? resolve(valid) : reject(valid)
}
})
}
props = [].concat(props)
if (props.length === 0) {
return
}
let errors = []
let count = 0
for (let i in props) {
const prop = props[i]
const value = utils.getValueByProp(model, prop)
utils.validateItem(rules, prop, value, (err) => {
if (err && err.length > 0) {
errors = errors.concat(err)
}
// 处理异步校验,等所有校验都结束时再callback
count++
if (count === props.length) {
if (errors.length > 0) {
if (options.showMessage) {
utils.showToast(errors[0].message)
}
callback(false, errors)
} else {
callback(true, null)
}
}
})
}
if (promise) {
return promise
}
},
validateItem(rules, prop, value, callback) {
if (!rules || JSON.stringify(rules) === '{}') {
if (callback instanceof Function) {
callback();
}
return true;
}
const propRules = [].concat(rules[prop] || []);
propRules.forEach((rule) => {
if (rule.pattern) {
rule.pattern = new RegExp(rule.pattern)
}
})
const descriptor = {
[prop]: propRules
};
const validator = new AsyncValidator(descriptor);
const model = {
[prop]: value
};
validator.validate(model, {
firstFields: true
}, (errors) => {
callback(errors);
});
},
getValueByProp: (obj, prop) => {
let tempObj = obj;
prop = prop.replace(/\[(\w+)\]/g, '.$1').replace(/^\./, '');
let keyArr = prop.split('.');
let i = 0;
for (let len = keyArr.length; i < len - 1; ++i) {
if (!tempObj) break;
let key = keyArr[i];
if (key in tempObj) {
tempObj = tempObj[key];
} else {
break;
}
}
return tempObj ? (typeof tempObj[keyArr[i]] === 'string' ? tempObj[keyArr[i]].trim() : tempObj[keyArr[i]]) :
null
},
showToast: (message) => {
uni.showToast({
title: message,
icon: 'none'
})
}
}
export default utils