Element UI 表单校验使用的是 async-validator
Ant Design 的form组件底层也是 async-validator
写一个简化版的async-validator
class Field {
constructor(rule, message) {
this.rule = rule;
this.message = message;
}
validate(value) {
return new Promise((resolve, reject) => {
if (typeof this.rule === 'function') {
this.rule(value)
.then(() => resolve())
.catch(error => reject(this.message || error));
} else if (typeof this.rule === 'object' && typeof this.rule.test === 'function') {
const result = this.rule.test(value);
if (result) {
resolve();
} else {
reject(this.message || '验证失败');
}
} else {
reject('无效的验证规则');
}
});
}
}
class AsyncValidator {
constructor(rules) {
this.rules = {};
Object.keys(rules).forEach(field => {
this.rules[field] = new Field(rules[field]);
});
}
validate(values) {
const promises = Object.keys(this.rules).map(field => {
const value = values[field];
return this.rules[field].validate(value);
});
return Promise.all(promises).then(() => {
return { errors: {} };
}).catch(errors => {
const errorObj = {};
errors.forEach(error => {
errorObj[error.field] = error.message;
});
return { errors: errorObj };
});
}
}
// 使用示例:
const rules = {
username: {
rule: value => new Promise((resolve, reject) => {
setTimeout(() => {
if (value.length < 5) {
reject('用户名长度至少为5个字符');
} else {
resolve();
}
}, 1000);
}),
message: '用户名错误'
},
email: {
rule: { test: value => /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value) },
message: '邮箱格式不正确'
}
};
const validator = new AsyncValidator(rules);
validator.validate({ username: 'user', email: 'invalid_email' })
.then(result => console.log(result))
.catch(errors => console.log(errors));