antd4 form自定义校验validator

977 阅读1分钟

接收Promise作为返回值,校验通过可以返回Promise.resolve(),校验失败可以返回Promise.reject(new Error('错误提示信息'));

依赖其它表单项值决定校验结果

如下示例可以通过自定义校验确定两次密码输入是否一致。

// 校验两次密码一致
const validatorPassword = (rule: RuleConfig, value: string) => {
  const { getFieldValue } = form;
  const password = getFieldValue('password');
  if (password && value && value === password) {
    return Promise.resolve();
  } else {
    return Promise.reject(new Error('请保证两次密码输入一致'));
  }
}

<Form>
  <Form.Item
    label="新密码"
    name="password"
    rules={[{ required: true, message: '请输入新密码' }]}
  >
    <Input.Password placeholder='请输入新密码' />
  </Form.Item>
  <Form.Item
    label="确认新密码"
    name="newPassword"
    rules={[
      { required: true, message: '请确认新密码' }
      { validator: validatorPassword }
    ]}
  >
    <Input.Password placeholder='请确认新密码' />
  </Form.Item>
</Form>

依赖接口结果决定校验结果

  • 通过自定义校验从接口确定输入的名称是否重复。
// 校验名称是否重复
const validatorName = async(rule: RuleConfig, value: string) => {
  const res = await validNameRequest({ name: value });
  if (res.data?.data) {
    return Promise.resolve();
  } else {
    return Promise.reject(new Error('名称重复'));
  }
}

<Form.Item
  label="名称"
  name="name"
  rules={[
    { required: true, message: '请输入名称' },
    { validator: validatorName }
  ]}
>
  <Input placeholder='请输入名称' />
</Form.Item>
  • 通过自定义校验从接口确定输入的名称是否重复(添加防抖逻辑减少接口请求次数)。

由于form的validator接收Promise作为返回值,所以需要使用返回一个promise函数的debounce函数包裹我们自定义校验的函数。

// 返回一个promise函数的debounce
const promiseDebounce = (fun: Function, delay: number) => {
  let timer: ReturnType<typeof setTimeout>;
  return (...args: any[]) => {
    if (timer) {
      clearTimeout(timer);
    }
    return new Promise((resolve) => {
      timer = setTimeout(() => {
        clearTimeout(timer);
        resolve(fun.apply(null, args));
      }, delay);
    });
  };
}

// 校验名称是否重复
const validatorName = async(rule: RuleConfig, value: string) => {
  const res = await validNameRequest({ name: value });
  if (res.data?.data) {
    return Promise.resolve();
  } else {
    return Promise.reject(new Error('名称重复'));
  }
}

<Form.Item
  label="名称"
  name="name"
  rules={[
    { required: true, message: '请输入名称' },
    { validator: promiseDebounce(validatorName, 600) }
  ]}
>
  <Input placeholder='请输入名称' />
</Form.Item>