• English
  • LoginForm/Page

    LoginForm and LoginFormPage are ProForm variants tailored for typical login compositions and reduce layout friction.

    Login form

    LoginForm
    import {
      AlipayCircleOutlined,
      LockOutlined,
      MobileOutlined,
      TaobaoCircleOutlined,
      UserOutlined,
      WeiboCircleOutlined,
    } from '@ant-design/icons';
    import {
      LoginForm,
      ProConfigProvider,
      ProFormCaptcha,
      ProFormCheckbox,
      ProFormText,
      setAlpha,
    } from '@ant-design/pro-components';
    import { Space, Tabs, message, theme } from 'antd';
    import type { CSSProperties } from 'react';
    import { useState } from 'react';
    
    type LoginType = 'phone' | 'account';
    
    const Demo = () => {
      const { token } = theme.useToken();
      const [loginType, setLoginType] = useState<LoginType>('phone');
    
      const iconStyles: CSSProperties = {
        marginInlineStart: '16px',
        color: setAlpha(token.colorTextBase, 0.2),
        fontSize: '24px',
        verticalAlign: 'middle',
        cursor: 'pointer',
      };
    
      return (
        <ProConfigProvider hashed={false}>
          <div style={{ backgroundColor: token.colorBgContainer }}>
            <LoginForm
              logo="https://github.githubassets.com/favicons/favicon.png"
              title="Github"
              subTitle="全球最大的代码托管平台"
              actions={
                <Space>
                  其他登录方式
                  <AlipayCircleOutlined style={iconStyles} />
                  <TaobaoCircleOutlined style={iconStyles} />
                  <WeiboCircleOutlined style={iconStyles} />
                </Space>
              }
            >
              <Tabs
                centered
                activeKey={loginType}
                onChange={(activeKey) => setLoginType(activeKey as LoginType)}
                items={[
                  { key: 'account', label: '账号密码登录' },
                  { key: 'phone', label: '手机号登录' },
                ]}
              />
              {loginType === 'account' && (
                <>
                  <ProFormText
                    name="username"
                    fieldProps={{
                      size: 'large',
                      prefix: <UserOutlined className={'prefixIcon'} />,
                    }}
                    placeholder={'用户名: admin or user'}
                    rules={[
                      {
                        required: true,
                        message: '请输入用户名!',
                      },
                    ]}
                  />
                  <ProFormText.Password
                    name="password"
                    fieldProps={{
                      size: 'large',
                      prefix: <LockOutlined className={'prefixIcon'} />,
                      strengthText:
                        'Password should contain numbers, letters and special characters, at least 8 characters long.',
                      statusRender: (value) => {
                        const getStatus = () => {
                          if (value && value.length > 12) {
                            return 'ok';
                          }
                          if (value && value.length > 6) {
                            return 'pass';
                          }
                          return 'poor';
                        };
                        const status = getStatus();
                        if (status === 'pass') {
                          return (
                            <div style={{ color: token.colorWarning }}>
                              强度:中
                            </div>
                          );
                        }
                        if (status === 'ok') {
                          return (
                            <div style={{ color: token.colorSuccess }}>
                              强度:强
                            </div>
                          );
                        }
                        return (
                          <div style={{ color: token.colorError }}>强度:弱</div>
                        );
                      },
                    }}
                    placeholder={'密码: ant.design'}
                    rules={[
                      {
                        required: true,
                        message: '请输入密码!',
                      },
                    ]}
                  />
                </>
              )}
              {loginType === 'phone' && (
                <>
                  <ProFormText
                    fieldProps={{
                      size: 'large',
                      prefix: <MobileOutlined className={'prefixIcon'} />,
                    }}
                    name="mobile"
                    placeholder={'手机号'}
                    rules={[
                      {
                        required: true,
                        message: '请输入手机号!',
                      },
                      {
                        pattern: /^1\d{10}$/,
                        message: '手机号格式错误!',
                      },
                    ]}
                  />
                  <ProFormCaptcha
                    fieldProps={{
                      size: 'large',
                      prefix: <LockOutlined className={'prefixIcon'} />,
                    }}
                    captchaProps={{
                      size: 'large',
                    }}
                    placeholder={'请输入验证码'}
                    captchaTextRender={(timing, count) => {
                      if (timing) {
                        return `${count} ${'获取验证码'}`;
                      }
                      return '获取验证码';
                    }}
                    name="captcha"
                    rules={[
                      {
                        required: true,
                        message: '请输入验证码!',
                      },
                    ]}
                    onGetCaptcha={async () => {
                      message.success('获取验证码成功!验证码为:1234');
                    }}
                  />
                </>
              )}
              <div
                style={{
                  marginBlockEnd: 24,
                }}
              >
                <ProFormCheckbox noStyle name="autoLogin">
                  自动登录
                </ProFormCheckbox>
                <a
                  style={{
                    float: 'right',
                  }}
                >
                  忘记密码
                </a>
              </div>
            </LoginForm>
          </div>
        </ProConfigProvider>
      );
    };
    
    export default () => (
      <div style={{ padding: 24 }}>
        <Demo />
      </div>
    );
    

    Full-page login shell

    Full-page LoginForm
    import {
      AlipayOutlined,
      LockOutlined,
      MobileOutlined,
      TaobaoOutlined,
      UserOutlined,
      WeiboOutlined,
    } from '@ant-design/icons';
    import {
      LoginFormPage,
      ProConfigProvider,
      ProFormCaptcha,
      ProFormCheckbox,
      ProFormText,
    } from '@ant-design/pro-components';
    import { Button, Divider, Space, Tabs, message, theme } from 'antd';
    import type { CSSProperties } from 'react';
    import { useState } from 'react';
    
    type LoginType = 'phone' | 'account';
    
    const iconStyles: CSSProperties = {
      color: 'rgba(0, 0, 0, 0.2)',
      fontSize: '18px',
      verticalAlign: 'middle',
      cursor: 'pointer',
    };
    
    const Page = () => {
      const [loginType, _setLoginType] = useState<LoginType>('phone');
      const { token } = theme.useToken();
      return (
        <div
          style={{
            backgroundColor: 'white',
            height: '100vh',
          }}
        >
          <LoginFormPage
            backgroundImageUrl="https://mdn.alipayobjects.com/huamei_gcee1x/afts/img/A*y0ZTS6WLwvgAAAAAAAAAAAAADml6AQ/fmt.webp"
            logo="https://github.githubassets.com/favicons/favicon.png"
            backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr"
            title="Github"
            containerStyle={{
              backgroundColor: 'rgba(0, 0, 0,0.65)',
              backdropFilter: 'blur(4px)',
            }}
            subTitle="全球最大的代码托管平台"
            activityConfig={{
              style: {
                boxShadow: '0px 0px 8px rgba(0, 0, 0, 0.2)',
                color: token.colorTextHeading,
                borderRadius: 8,
                backgroundColor: 'rgba(255,255,255,0.25)',
                backdropFilter: 'blur(4px)',
              },
              title: '活动标题,可配置图片',
              subTitle: '活动介绍说明文字',
              action: (
                <Button
                  size="large"
                  style={{
                    borderRadius: 20,
                    background: token.colorBgElevated,
                    color: token.colorPrimary,
                    width: 120,
                  }}
                >
                  去看看
                </Button>
              ),
            }}
            actions={
              <div
                style={{
                  display: 'flex',
                  justifyContent: 'center',
                  alignItems: 'center',
                  flexDirection: 'column',
                }}
              >
                <Divider plain>
                  <span
                    style={{
                      color: token.colorTextPlaceholder,
                      fontWeight: 'normal',
                      fontSize: 14,
                    }}
                  >
                    其他登录方式
                  </span>
                </Divider>
                <Space align="center" size={24}>
                  <div
                    style={{
                      display: 'flex',
                      justifyContent: 'center',
                      alignItems: 'center',
                      flexDirection: 'column',
                      height: 40,
                      width: 40,
                      border: '1px solid ' + token.colorPrimaryBorder,
                      borderRadius: '50%',
                    }}
                  >
                    <AlipayOutlined style={{ ...iconStyles, color: '#1677FF' }} />
                  </div>
                  <div
                    style={{
                      display: 'flex',
                      justifyContent: 'center',
                      alignItems: 'center',
                      flexDirection: 'column',
                      height: 40,
                      width: 40,
                      border: '1px solid ' + token.colorPrimaryBorder,
                      borderRadius: '50%',
                    }}
                  >
                    <TaobaoOutlined style={{ ...iconStyles, color: '#FF6A10' }} />
                  </div>
                  <div
                    style={{
                      display: 'flex',
                      justifyContent: 'center',
                      alignItems: 'center',
                      flexDirection: 'column',
                      height: 40,
                      width: 40,
                      border: '1px solid ' + token.colorPrimaryBorder,
                      borderRadius: '50%',
                    }}
                  >
                    <WeiboOutlined style={{ ...iconStyles, color: '#1890ff' }} />
                  </div>
                </Space>
              </div>
            }
          >
            <Tabs
              items={[
                { key: 'account', label: '账号密码登录' },
                { key: 'phone', label: '手机号登录' },
              ]}
            />
            {loginType === 'account' && (
              <>
                <ProFormText
                  name="username"
                  fieldProps={{
                    size: 'large',
                    prefix: (
                      <UserOutlined
                        style={{
                          color: token.colorText,
                        }}
                        className={'prefixIcon'}
                      />
                    ),
                  }}
                  placeholder={'用户名: admin or user'}
                  rules={[
                    {
                      required: true,
                      message: '请输入用户名!',
                    },
                  ]}
                />
                <ProFormText.Password
                  name="password"
                  fieldProps={{
                    size: 'large',
                    prefix: (
                      <LockOutlined
                        style={{
                          color: token.colorText,
                        }}
                        className={'prefixIcon'}
                      />
                    ),
                  }}
                  placeholder={'密码: ant.design'}
                  rules={[
                    {
                      required: true,
                      message: '请输入密码!',
                    },
                  ]}
                />
              </>
            )}
            {loginType === 'phone' && (
              <>
                <ProFormText
                  fieldProps={{
                    size: 'large',
                    prefix: (
                      <MobileOutlined
                        style={{
                          color: token.colorText,
                        }}
                        className={'prefixIcon'}
                      />
                    ),
                  }}
                  name="mobile"
                  placeholder={'手机号'}
                  rules={[
                    {
                      required: true,
                      message: '请输入手机号!',
                    },
                    {
                      pattern: /^1\d{10}$/,
                      message: '手机号格式错误!',
                    },
                  ]}
                />
                <ProFormCaptcha
                  fieldProps={{
                    size: 'large',
                    prefix: (
                      <LockOutlined
                        style={{
                          color: token.colorText,
                        }}
                        className={'prefixIcon'}
                      />
                    ),
                  }}
                  captchaProps={{
                    size: 'large',
                  }}
                  placeholder={'请输入验证码'}
                  captchaTextRender={(timing, count) => {
                    if (timing) {
                      return `${count} ${'获取验证码'}`;
                    }
                    return '获取验证码';
                  }}
                  name="captcha"
                  rules={[
                    {
                      required: true,
                      message: '请输入验证码!',
                    },
                  ]}
                  onGetCaptcha={async () => {
                    message.success('获取验证码成功!验证码为:1234');
                  }}
                />
              </>
            )}
            <div
              style={{
                marginBlockEnd: 24,
              }}
            >
              <ProFormCheckbox noStyle name="autoLogin">
                自动登录
              </ProFormCheckbox>
              <a
                style={{
                  float: 'right',
                }}
              >
                忘记密码
              </a>
            </div>
          </LoginFormPage>
        </div>
      );
    };
    
    const Demo = () => {
      return (
        <ProConfigProvider dark>
          <Page />
        </ProConfigProvider>
      );
    };
    
    export default () => (
      <div style={{ padding: 24 }}>
        <Demo />
      </div>
    );
    

    LoginForm

    LoginForm represents the more common centered layout style.

    parameterdescriptiontypedefault value
    logoConfiguration of logo, supports ReactNode and stringReactNode-
    titletitle, can be emptyReactNode | false-
    subTitleSecondary title, can be configured as emptyReactNode | false-
    actionsCustomize additional login functionalityReactNode-
    messageA prompt configuration at the top of the form, you can configure some error messageReactNode | false-
    contentStyleStyle of the main login boxReact.CSSProperties-
    containerStyleStyle of the login containerReact.CSSProperties-
    otherStyleStyle of other areasReact.CSSProperties-

    LoginFormPage

    LoginFormPage uses the left and right layout, and adds some ad slot configuration.

    parameterdescriptiontypedefault value
    logoConfiguration of logo, supports ReactNode and stringReactNode | string-
    titletitle, can be emptyReactNode | false-
    subTitleSecondary title, can be configured as emptyReactNode | false-
    actionsCustomize additional login functionalityReactNode-
    messageA prompt configuration at the top of the form, you can configure some error messageReactNode | false-
    backgroundImageUrlThe background image configuration of the entire area, it will not be displayed on the mobile phonestring-
    backgroundVideoUrlThe background video configuration of the entire area, takes priority over backgroundImageUrlstring-
    activityConfigThe configuration of the activity, including title, subTitle, action, which represent the title, subtitle and action button respectively. You can also configure style to control the style of the area{title,subTitle,action,style}-
    containerStyleStyle of the containerReact.CSSProperties-
    mainStyleStyle of the main areaReact.CSSProperties-
    otherStyleStyle of other areasReact.CSSProperties-