• 中文
  • 登录表单

    LoginForm 和 LoginFormPage 是 ProForm 的变体,两者是为了适应常见的登录表单布局来专门实现,适用于各类登录场景,降低布局的压力。

    登录表单

    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>
    );
    

    页面级别的登录表单

    页面级别的表单
    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>
    );
    

    API

    LoginForm

    LoginForm 代表了比较常见的居中布局样式。

    参数说明类型默认值
    logologo 的配置,支持 ReactNode 和 stringReactNode-
    title标题,可以配置为空ReactNode | false-
    subTitle二级标题,可以配置为空ReactNode | false-
    actions自定义额外的登录功能ReactNode-
    messageform 顶部的一个提示配置,可以配置一些错误的提示信息ReactNode | false-
    contentStyle登录框主表格的样式React.CSSProperties-
    containerStyle登录框容器的样式React.CSSProperties-
    otherStyle其他区域的样式React.CSSProperties-

    LoginFormPage

    LoginFormPage 使用了左右布局,并且增加了一些广告位的配置。

    参数说明类型默认值
    logologo 的配置,支持 ReactNode 和 stringReactNode | string-
    title标题,可以配置为空ReactNode | false-
    subTitle二级标题,可以配置为空ReactNode | false-
    actions自定义额外的登录功能ReactNode-
    messageform 顶部的一个提示配置,可以配置一些错误的提示信息ReactNode | false-
    backgroundImageUrl整个区域的背景图片配置,手机端不会展示string-
    backgroundVideoUrl整个区域的背景视频配置,优先级高于 backgroundImageUrlstring-
    activityConfig活动的配置,包含 title,subTitle,action,分别代表标题,次标题和行动按钮,也可配置 style 来控制区域的样式{title,subTitle,action,style}-
    containerStyle容器的样式React.CSSProperties-
    mainStyle主区域的样式React.CSSProperties-
    otherStyle其他区域的样式React.CSSProperties-