今天制作登陆界面,本来想找开原的代码复制粘贴,但奈何网友们是在太过吝啬。找了半天,不如我来做这个开源。
代码如下(登陆界面层级都比较分明,故不再做过多解释)
import styles from './login.module.scss';
import { Button, Checkbox, Form, Input, Tabs } from 'antd';
import { UserOutlined, MedicineBoxOutlined, VerifiedOutlined, TabletOutlined } from '@ant-design/icons';
import type { TabsProps } from 'antd';
import React, { useState, useEffect } from 'react';
import Router from 'next/router';
const Login = () => {
// 刷新验证码的函数
const refreshCaptcha = () => {
fetchCaptcha();
};
const [captcha, setCaptcha] = useState<string | null>(null);
const [sendButton, setSendButton] = useState('发送验证码');
const [isSending, setIsSending] = useState(false);
const [countdown, setCountdown] = useState(0);
useEffect(() => {
let timer: NodeJS.Timeout;
if (countdown > 0) {
timer = setTimeout(() => {
setCountdown(countdown - 1);
setSendButton(`重新发送(${countdown - 1}s)`);
}, 1000);
} else if (countdown === 0 && isSending) {
setIsSending(false);
setSendButton('发送验证码');
}
return () => clearTimeout(timer);
}, [countdown, isSending]);
const sendCap = () => {
setIsSending(true);
setCountdown(60);
};
// 注册事件
const [activeKey, setActiveKey] = useState('1');
const [enrollText, setEnrollText] = useState('手机登录');
const enroll = () => {
setEnrollText('手机注册');
setActiveKey('2'); // 切换到第二个选项卡
};
const items: TabsProps['items'] = [
{
key: '1',
label: '账号登录',
children: (
<>
<Form.Item>
<Input size="large" placeholder="请输入账户" prefix={<UserOutlined />} allowClear />
</Form.Item>
<Form.Item name="password" rules={[{ required: true, message: '密码不能为空' }]}>
<Input size="large" prefix={<MedicineBoxOutlined />} type="password" placeholder="密码" allowClear />
</Form.Item>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Input style={{ height: 40, marginRight: '20px' }} size="large" prefix={<VerifiedOutlined />} allowClear />
<img src={captcha || ''} alt="验证码" onClick={refreshCaptcha} style={{ width: '100px', height: '50px' }} />
</div>
<Form.Item>
<Form.Item name="remember" valuePropName="checked">
<div
style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '10px' }}
>
<Checkbox>记住我</Checkbox>
<Button type={'link'} size="large" style={{ float: 'right' }}>
忘记密码
</Button>
</div>
</Form.Item>
</Form.Item>
<Button type="primary" htmlType="submit" block>
登 录
</Button>
<div
style={{
width: '100%',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: '10px',
}}
>
<p>或者</p>
<Button style={{ float: 'right' }} type={'link'} onClick={enroll}>
注册
</Button>
</div>
</>
),
},
{
key: '2',
label: `${enrollText}`,
children: (
<>
<Form.Item>
<Input size="large" placeholder="请输入手机号" prefix={<TabletOutlined />} allowClear />
</Form.Item>
<Form.Item>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Input
style={{ width: '60%' }}
size="large"
prefix={<VerifiedOutlined />}
allowClear
placeholder="请输入验证码"
/>
<Button size="large" onClick={sendCap} disabled={isSending} style={{ fontSize: 12 }}>
{sendButton}
</Button>
</div>
</Form.Item>
{enrollText === '手机注册' ? (
<>
<Form.Item>
<Input size="large" placeholder="设置密码" prefix={<TabletOutlined />} type="password" allowClear />
</Form.Item>
<Form.Item>
<Input size="large" placeholder="确认密码" prefix={<TabletOutlined />} type="password" allowClear />
</Form.Item>
</>
) : (
<></>
)}
<Button size="large" type="primary" htmlType="submit" block style={{ marginTop: '' }}>
登 录
</Button>
</>
),
},
];
const onChange = key => {
key === '1' ? setEnrollText('手机登录') : console.log('当前激活的选项卡:', key);
setActiveKey(key); // 更新当前激活的选项卡
};
async function fetchCaptcha() {
try {
const response = await fetch('/api/captcha'); // 使用相对路径
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
setCaptcha(data.imageSrc);
} catch (error) {
console.error('Error fetching captcha:', error);
}
}
useEffect(() => {
// fetchCaptcha();
}, []);
return (
<div className={styles.container}>
<Form
name="normal_login"
className="login-form"
initialValues={{ remember: true }}
style={{
width: '400px',
height: '550px',
marginTop: '15%',
background: '#fff',
padding: 50,
borderRadius: '6px',
}}
>
<h1 style={{ fontSize: '20px' }}>个人管理基础信息平台 </h1>
<Tabs
items={items}
centered
defaultActiveKey="1"
onChange={onChange}
onTabClick={onChange}
activeKey={activeKey}
></Tabs>
</Form>
</div>
);
};
export default Login;
代码的显示效果是这样的
我认为这个页面的特色还是有的,使用一个tabs标签实现两个点击按钮实现了三个和功能页面转换。其中图形验证码在业务上实际是由后端生成的。所以自行修改。
如果你认为它还能更好,请联系我。我们共同讨论!