最近在學(xué) react ,所以就順手寫一個
Todolist
作為練手項目。
github 地址 : ReactMall
可以直接用 webstorm 直接 create
由于react配置less沒有像vue那種那么方便,所以我們需要執(zhí)行下面這個來進行配置
yarn eject
完成之后我們就會出現(xiàn)這個配置文件夾,然后我們用 webpack.config.js
這個文件進行操作
sassModuleRegex
,然后我們在大概 528 行左右的位置插入以下的片段。
{
test: /\.less$/,
use :getStyleLoaders({
},'less-loader')
},
然后我們再創(chuàng)建幾個文件夾作為目錄入口
因為我們的 login、register 是類似的功能的,所以就放在了同層級路由上面。
然后 list 我們就放在主頁下面吧,其實直接用主頁面也行,但是為了路由規(guī)范一點,讓我們知道這個路由下的功能是啥,就還是 list 了。
import App from "../App";
import Login from "../pages/Login";
import Register from "../pages/Register";
import {BrowserRouter as Router,Routes,Route} from 'react-router-dom'
import List from "../pages/List";
const BaseRouter = () => (
<Router>
<Routes>
<Route path='/' element={<App />}>
<Route path='/list' element={<List/>}></Route>
</Route>
<Route path='/login' element={<Login/>}></Route>
<Route path='/register' element={<Register/>}></Route>
</Routes>
</Router>
)
export default BaseRouter
在 List.jsx、Login.jsx、Register.jsx 直接放上一些模版代碼。先代替一下,檢測看看能不能渲染出來,后續(xù)再進行替換。
import React from 'react';
function Register() {
return (
<div>
Register
</div>
)
}
export default Register;
這一層我們是做request請求使用,用于請求后臺的數(shù)據(jù)。
再src下新建一個request文件夾用來放 api 接口等等…
如果沒有axios的話,記得提前 yarn add axios
import axios from 'axios'
// 配置項
const axiosOption = {
baseURL: 'http://localhost:4000/api/v1',
timeout: 5000
}
// 創(chuàng)建一個單例
const instance = axios.create(axiosOption);
// 添加請求攔截器
instance.interceptors.request.use(function (config){
let token = localStorage.getItem('token')
if (token){
config.headers={
'Authorization':token
}
}
return config;
}, function (error){
// 對請求錯誤做些什么
return Promise.reject(error);
})
// 添加相應(yīng)攔截器
instance.interceptors.response.use(function (response){
// 對響應(yīng)頭的數(shù)據(jù)做處理
return response.data;
}, function (error){
return Promise.reject(error)
});
export default instance;
這是兩個后臺的接口,分別是登陸和注冊。
export const RegisterApi =(params)=> request.post('/user/register',params)
export const LoginApi =(params)=> request.post('/user/login',params)
請求后臺數(shù)據(jù)
const onFinish = (values) => {
LoginApi({
user_name: values.username,
password: values.password
}).then(res => {
console.log(res)
if(res.status===200){
localStorage.setItem("token",res.data.token);
localStorage.setItem("user_name",res.data.user.user_name);
localStorage.setItem("avatar","https://q1.qlogo.cn/g?b=qq&nk=3274661196&s=640")
message.success("登陸成功").then();
// 跳到登錄頁
setTimeout(()=>{
navigate('/list')
} ,800)
}else{
message.error(res.msg).then();
}
})
};
主體是一個 from 表單 對數(shù)據(jù)進行調(diào)試
<Form
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
autoComplete="off"
>
<Form.Item
name="username"
rules={[
{
required: true,
message: '請輸入用戶名!',
},
]}
>
<Input size='large' prefix={<UserOutlined className="site-form-item-icon" />} placeholder="請輸入用戶名"/>
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: '請輸入密碼!',
},
]}
>
<Input.Password size='large' prefix={<LockOutlined className="site-form-item-icon" />} placeholder="請輸入密碼"/>
</Form.Item>
<Form.Item>
<Link style={{
float: 'right',
}} to="/register">還沒賬號?立即注冊</Link>
</Form.Item>
<Form.Item>
<Button size='large' type="primary" htmlType="submit" block>
登陸
</Button>
</Form.Item>
</Form>
登陸頁面就像這個樣子
先看頁面樣子
頂部的 header 我們可以抽離一個 component 出來。就叫 Header.jsx
useEffect
進行初始化。
const [avatar,setAvatar]=useState('')
const [userName,setUserName]=useState("")
const navigate = useNavigate();
useEffect(()=>{
let username1 = localStorage.getItem('user_name')
let avatar1 = localStorage.getItem('avatar')
if(username1){
setUserName(username1)
}
if(avatar1){
setAvatar(avatar1)
}
},[]);
底部我們不需要展示什么信息,所以可以簡單一點嵌入到app中即可,但也可以抽離成組件,方便后續(xù)的擴展。
function App() {
return (
<Layout id='app'>
<Header />
<div className='container'>
<div className='container_box'>
<div className="container_content">
<Outlet />
</div>
</div>
</div>
<Footer className='footer_content'>TodoList | Copyright © 2023 Author FanOne</Footer>
</Layout>
)
}
還有一個中間部分的,由于涉及到了組件之間的傳遞,我們下一遍博客再講解。
所有的代碼都在github上:https://github.com/CocaineCong/react-mall
聯(lián)系客服