安装依赖
本项目用到的依赖可以在此预先安装好:
命令行:
npm i antd redux react-redux react-router-dom@6 axios less less-loader@6.0.0 --save
基础步骤:
第一步:
按照要求搭建项目结构
页面效果:
登录页面:
注册页面:
具体代码:
登录页面 Login.jsx
import React from 'react'
import { Form, Input, Button, message } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import {Link, useNavigate} from 'react-router-dom'
import "./less/Login.less"
import logoImg from '../assets/logo.png'
import {LoginApi} from '../request/api'
export default function Login() {
const navigate = useNavigate()
const onFinish = (values) => {
LoginApi({
username: values.username,
password: values.password
}).then(res=>{
if(res.errCode===0){
message.success(res.message)
// 存储数据
localStorage.setItem('avatar', res.data.avatar)
localStorage.setItem('cms-token', res.data['cms-token'])
localStorage.setItem('editable', res.data.editable)
localStorage.setItem('player', res.data.player)
localStorage.setItem('username', res.data.username)
// 跳转到根路径
setTimeout(()=>{
navigate('/')
}, 1500)
}else{
message.error(res.message)
}
})
};
return (
<div className="login">
<div className='login_box'>
<img src={logoImg} alt="" />
<Form
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
autoComplete="off"
>
<Form.Item
name="username"
rules={[
{
required: true,
message: '请输入用户名!',
},
]}
>
<Input size="large" prefix={<UserOutlined />} placeholder="请输入用户名" />
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: '请输入密码!',
},
]}
>
<Input.Password size="large" prefix={<LockOutlined />} placeholder="请输入密码" />
</Form.Item>
<Form.Item>
<Link to="/register">还没账号?立即注册</Link>
</Form.Item>
<Form.Item>
<Button size='large' type="primary" htmlType="submit" block>登录</Button>
</Form.Item>
</Form>
</div>
</div>
)
}
登录页面 css 样式:Login.css
.login {
background: #fff;
width: 100vw;
height: 100vh;
position: relative;
}
.login .login_box {
width: 450px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.login .login_box img {
display: block;
margin: 0 auto 20px;
width: 408px;
}
注册页面:
Register.jsx
import React from 'react'
import { Form, Input, Button, message } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import { Link, useNavigate } from 'react-router-dom'
import "./less/Login.less"
import logoImg from '../assets/logo.png'
import { RegisterApi } from '../request/api'
export default function Register() {
const navigate = useNavigate()
const onFinish = (values) => {
RegisterApi({
username: values.username,
password: values.password
}).then(res => {
if (res.errCode === 0) {
message.success(res.message);
// 跳到登录页
setTimeout(() => navigate('/login'), 1500)
} else {
message.error(res.message);
}
})
};
return (
<div className="login">
<div className='login_box'>
<img src={logoImg} alt="" />
<Form
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
autoComplete="off"
>
<Form.Item
name="username"
rules={[
{
required: true,
message: '请输入用户名!',
},
]}
>
<Input size="large" prefix={<UserOutlined />} placeholder="请输入用户名" />
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: '请输入密码!',
},
]}
>
<Input.Password size="large" prefix={<LockOutlined />} placeholder="请输入密码" />
</Form.Item>
<Form.Item
name="confirm"
dependencies={['password']}
hasFeedback
rules={[
{
required: true,
message: '请再次确认密码!',
},
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('请输入相同密码!'));
},
}),
]}
>
<Input.Password size="large" prefix={<LockOutlined />} placeholder="请再次确认密码" />
</Form.Item>
<Form.Item>
<Link to="/login">已有账号?前往登录</Link>
</Form.Item>
<Form.Item>
<Button size='large' type="primary" htmlType="submit" block>立即注册</Button>
</Form.Item>
</Form>
</div>
</div>
)
}
注册页面 css 样式(同登录页面):Login.css
基础操作:
第一步:
在 src 下创建 request 目录,并在其中创建 request.js 及 api.js。
第二步:
在 Register.jsx 中封装 axios 请求
import axios from 'axios'
// 配置项
const axiosOption = {
baseURL: '/api',
timeout: 5000
}
// 创建一个单例
const instance = axios.create(axiosOption);
export default instance;
第三步:在 api.js 中使用以下格式定义接口。
当项目体积过大,api 数量增多时,可以在各个文件夹下建立单独的 api 文件,实现模块化管理。
import request from './request'
export const xxApi = () => request.get('/xx')
页面效果:
具体代码:
request.js:
import axios from 'axios'
// 配置项
const axiosOption = {
baseURL: '/api',
timeout: 5000
}
// 创建一个单例
const instance = axios.create(axiosOption);
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
let token = localStorage.getItem('cms-token')
if(token){
config.headers = {
'cms-token': token
}
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 只需要 response 中的 data 数据
return response.data;
}, function (error) {
// 对于返回不同状态码的报错,前端可以针对不同的响应错误进行提示。
return Promise.reject(error);
});
export default instance;
api.js
import request from './request'
// 注册
export const RegisterApi = (params) => request.post('/register', params)
// 登录
export const LoginApi = (params) => request.post('/login', params)
阅读量:1862
点赞量:0
收藏量:0