React、Ant Design 5.0 构建通用后台管理系统 - 登录页面

发布时间 2023-04-24 16:42:53作者: EvilChan

安装依赖

npm install antd @ant-design/icons @ant-design/pro-components

Ant Design组件库
@ant-design/pro-components封装一些好用的常用组件库

main.tsx

import '@/styles/global.css'
import 'antd/dist/reset.css'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <App />
)

// React.StrictMode在开发时出现两次执行,开发时注释掉,部署时放开
// ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
//   <React.StrictMode>
//     <App />
//   </React.StrictMode>,
// )

添加了antd的reset样式,以及自定义样式global.css

src/styles/global.css

#root {
  height: 100%;
}

App.tsx

import Login from '@/pages/user/Login'
import { ConfigProvider } from 'antd'
import zhCN from 'antd/es/locale/zh_CN'
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'

function App() {
  // 路由对象转标签
  // const convert = (route: RouteObject) => {
  //   if (Array.isArray(route.children)) {
  //     return (
  //       <Route key={route.path} path={route.path} element={route.element}>
  //         {route.children.map((item) => convert(item))}
  //       </Route>
  //     )
  //   } else {
  //     return (
  //       <Route key={route.path} path={route.path} element={route.element} />
  //     )
  //   }
  // }

  return (
    <ConfigProvider locale={zhCN}>
      <BrowserRouter>
        <Routes>
          {/* 开发登录组件,默认跳转到登录页面,Navigate具有跳转功能 */}
          <Route path="*" element={<Navigate to={'/user/login'} />} />
          {/* 登录页面 */}
          <Route path="/user/login" element={<Login />} />
          {/* <Route
            element={
              <div>
                <Link to={'/'}>首页</Link>
                <Link to={'/system'}>系统管理</Link>
                <Outlet />
              </div>
            }
          >
            {routes.map((route) => convert(route))}
          </Route> */}
        </Routes>
      </BrowserRouter>
    </ConfigProvider>
  )
}

export default App

src/pages/user/Login/index.tsx

import { LockOutlined, MobileOutlined, UserOutlined } from '@ant-design/icons'
import {
  LoginForm,
  ProFormCaptcha,
  ProFormCheckbox,
  ProFormText,
} from '@ant-design/pro-components'
import { Tabs, message } from 'antd'
import { useState } from 'react'
import style from './style.module.css'

const enum LoginType {
  Account = 'account',
  Phone = 'phone',
}

function Login() {
  const [messageApi, contextHolder] = message.useMessage()
  const [loginType, setLoginType] = useState<LoginType>(LoginType.Account)
  return (
    <>
      {contextHolder}
      <div className={style.container}>
        <div className={style.content}>
          <LoginForm
            title="后台管理登录系统"
            subTitle="The Backend Login System."
          >
            <Tabs
              centered
              activeKey={loginType}
              onChange={(activeKey) => setLoginType(activeKey as LoginType)}
              items={[
                {
                  key: LoginType.Account,
                  label: '账号密码登录',
                },
                {
                  key: LoginType.Phone,
                  label: '手机号登录',
                },
              ]}
            />
            {loginType === LoginType.Account && (
              <>
                <ProFormText
                  name={'username'}
                  fieldProps={{
                    size: 'large',
                    prefix: <UserOutlined />,
                  }}
                  placeholder={'用户名'}
                  rules={[
                    {
                      required: true,
                      message: '请输入用户名!',
                    },
                  ]}
                />
                <ProFormText.Password
                  name={'password'}
                  fieldProps={{
                    size: 'large',
                    prefix: <LockOutlined />,
                  }}
                  placeholder={'密码'}
                  rules={[
                    {
                      required: true,
                      message: '请输入密码!',
                    },
                  ]}
                />
              </>
            )}
            {loginType === LoginType.Phone && (
              <>
                <ProFormText
                  name={'mobile'}
                  fieldProps={{
                    size: 'large',
                    prefix: <MobileOutlined />,
                  }}
                  placeholder={'手机号'}
                  rules={[
                    {
                      required: true,
                      message: '请输入手机号!',
                    },
                  ]}
                />
                <ProFormCaptcha
                  name={'captcha'}
                  fieldProps={{
                    size: 'large',
                    prefix: <LockOutlined />,
                  }}
                  captchaProps={{
                    size: 'large',
                  }}
                  placeholder={'请输入验证码'}
                  captchaTextRender={(timing, count) => {
                    if (timing) {
                      return `${count} 获取验证码`
                    }
                    return '获取验证码'
                  }}
                  onGetCaptcha={async () => {
                    messageApi.success(`获取验证码成功! 验证码为1234`)
                  }}
                />
              </>
            )}
            <div
              style={{
                marginBlockEnd: 24,
              }}
            >
              <ProFormCheckbox noStyle name={'autoLogin'}>
                自动登录
              </ProFormCheckbox>
              <a style={{ float: 'right' }}>忘记密码?</a>
              <div style={{ clear: 'both' }}></div>
            </div>
          </LoginForm>
        </div>
      </div>
    </>
  )
}

export default Login

src/pages/user/Login/style.module.css

.container {
  height: 100%;
  background-image: url("/images/login_bg.svg");
  background-size: 100%;
  background-position: center 110px;
  background-repeat: no-repeat;
  background-color: #f0f2f5;
}

.container .content {
  padding-top: 40px;
}

请自备背景图,存放在src/public/images/上,或者自定义路径都行

至此,中规中矩的登录页面做好,下一章会编写api接口,sql建表语句等等