react项目Ant design-Form表单自定义校验

react项目Ant design-Form表单自定义校验

1. 需求:

  • 密码框的校验提示自定义:
    • 非空状态下,需判断输入的密码长度、字符规则是否符合;对于符合规则的校验,将图标颜色修改为#28C81F;
    • 密码框为空的状态下,使用form组件自带的错误提示;

2. 效果图:

在这里插入图片描述

在这里插入图片描述

3. 实现代码

1) 逻辑代码

// 注册-表单SignInForm.tsx
import React, { useState } from 'react';
import { Button, Form, FormProps, Input, Space } from 'antd';
import { CheckCircleFilled } from '@ant-design/icons';


type FieldType = {
    password?: string;
}
type passwordRulesType = {
    length: boolean;
    uppercase: boolean;
    specialChar: boolean;
    complexity: boolean;
}

export const SignInForm: React.FC<null> = () => {
    const [form] = Form.useForm<FieldType>();

    const onFinish: FormProps<FieldType>['onFinish'] = (values: FieldType) => {
        console.log('校验成功,下一步:', values);
    };
    const onFinishFailed: FormProps<FieldType>['onFinishFailed'] = (errorInfo) => {
        console.log('onFinishFailed:', errorInfo);
    };

    // 自定义密码校验
    const [passwordRules, setPasswordRules] = useState<passwordRulesType>({
        length: false,
        uppercase: false,
        specialChar: false,
        complexity: false
    });
    const validatePassword = (pwd: string) => {
        const length = pwd.length >= 8 && pwd.length <= 20;//支持8 - 20个字符,长度至少为8个字符
        const uppercase = /[A-Z]/.test(pwd);//至少包含一个大写字母
        const specialChar = /[!@#$%^&*(),.?":{}|<>]/.test(pwd);//至少包含一个特殊字符
        const complexity = uppercase && specialChar && /\d/.test(pwd);//必须包含数字、英文字母和特殊符号

        setPasswordRules({
            length,
            uppercase,
            specialChar,
            complexity
        });
        return Object.values(passwordRules).every(item => item === true);
    };
    const renderPasswordRules = () => (
        <div className='C-render-password-rules'>
            <Space>
                <CheckCircleFilled style={{ color: passwordRules.length ? '#28C81F' : '#D9D9D9' }} />
                <span style={{ color: '#D9D9D9' }}>支持8 - 20个字符,长度至少为8个字符</span>
            </Space>
            <Space>
                <CheckCircleFilled style={{ color: passwordRules.uppercase ? '#28C81F' : '#D9D9D9' }} />
                <span style={{ color: '#D9D9D9' }}>至少包含一个大写字母</span>
            </Space>
            <Space>
                <CheckCircleFilled style={{ color: passwordRules.specialChar ? '#28C81F' : '#D9D9D9' }} />
                <span style={{ color: '#D9D9D9' }}>至少包含一个特殊字符</span>
            </Space>
            <Space>
                <CheckCircleFilled style={{ color: passwordRules.complexity ? '#28C81F' : '#D9D9D9' }} />
                <span style={{ color: '#D9D9D9' }}>必须包含数字、英文字母和特殊符号</span>
            </Space>
        </div>
    );

    return (
        <>
            <div className={'C-signIn-form flex flex-col items-center'}>
                <div className='w-full flex flex-col items-center'>
                    <div style={{ fontSize: '36px' }}>Create your account</div>
                </div>
                <div className='w-[330px] mt-[25px]'>
                    <Form
                        form={form}
                        layout='vertical'
                        size='large'
                        style={{ maxWidth: '330px' }}
                        onFinish={onFinish}
                        onFinishFailed={onFinishFailed}
                    >
                        <Form.Item<FieldType>
                            label='Password'
                            name='password'
                            rules={[
                                ({ getFieldValue }) => ({
                                    validator(_, value) {
                                        if (!value) {
                                            setPasswordRules({
                                                length: false,
                                                uppercase: false,
                                                specialChar: false,
                                                complexity: false
                                            });
                                            return Promise.reject(new Error('Please enter your password'));
                                        }
                                        if (value === getFieldValue('password')) {
                                            if (!validatePassword(value)) {
                                                return Promise.reject(new Error(''));
                                            }
                                        }
                                        return Promise.resolve();
                                    }
                                })
                            ]}
                        >
                            <div>
                                <Input.Password placeholder='Enter your password' />
                                {renderPasswordRules()}
                            </div>
                        </Form.Item>
                        <Form.Item style={{ marginTop: '25px' }}>
                            <Button type='primary' block onClick={() => form.submit()}>Next</Button>
                        </Form.Item>
                    </Form>
                </div>
            </div>
        </>
    );
};

2) 样式

.C-signIn-form {
  .ant-form-vertical .ant-form-item:not(.ant-form-item-horizontal) .ant-form-item-label {
    font-weight: bold;
    padding: unset;

    .ant-form-item-required::before {
      content: '' !important;
    }
  }
}

.C-render-password-rules {
  position: absolute;
  top: 0;
  left: calc(100% + 20px);
  width: max-content;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

4. 注意事项:

  • <Form.Item>组件的内容如果需要自定义,需要保持只有一个根元素;
  • Button组件type='primary'需添加onClick={() => form.submit()}才会在点击按钮时触发表单的提交;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值