做一个需求,在表单元素输入时做验证:
这是表单元素:
<Form.Item
label="用户名"
name="username"
validateTrigger={["onBlur", "onChange"]}
rules={[
{ validator: usernameCheck }
]}
hasFeedback
>
<Input
className='input'
bordered={false}
/>
</Form.Item>
这是validator方法:
interface ValidateFunction {
(rule: any, value: any): void;
}
const usernameCheck: ValidateFunction = debounce(
async (_: any, value: any) => {
if (!value || value.length < 4) {
return Promise.reject('用户名太短了,至少4位');
} else if (value.length > 15) {
return Promise.reject('用户名太长了,超过了15位');
}
let res;
try {
res = await checkUsername(value)
} catch (e) {
return Promise.reject('网络故障,请稍后重试');
}
if (res) {
return Promise.reject('用户名已经被注册了');
}
return Promise.resolve();
}
)
使用了debounce方法,可以直接从lodash中,我这边是直接手写:
debounce方法(ts版)
interface SourceFunction {
(...args: any[]): any;
}
interface TargetFunction {
(...args: any[]): void;
}
export function debounce(
fun: SourceFunction,
delay: number = 500
): TargetFunction {
// 使用类型推断
let timer: ReturnType<typeof setTimeout>;
return async function (...args: any[]) {
if (timer) {
clearTimeout(timer);
}
return new Promise((resolve) => {
timer = setTimeout(() => {
clearTimeout(timer);
resolve(fun.apply(null, args));
}, delay);
});
};
}
需要注意的是,根据antd的官方文档,表单验证方法必须要返回一个Promise对象,根据Promise的对象的状态来判断验证是否通过。如果不返回Promise则会抛出未捕获的异常。