被安排了一个pc端项目,ui图只有8张,看着十分简单,就想用react写一下,顺便熟悉一下,但是由于没学多少不太会,遇到了很多问题,磕磕绊绊的也算是写完了。
页面展示
部分页面是比较相似的,这里就不展示了
路由
react路由官方文档
react支持两种路由模式:BrowserRouter 和 HashHistory,区别是HashHistory生产的链接中会有一个#,如http://localhost:5173/#/layout/putOrder,使用BrowserRouter 模式需在服务端进行配置,不然线上访问可能会遇到页面一刷新就404的情况,这里我使用HashHistory模式。
可以使用createBrowserRouter的方式创建路由,也可以选择使用<HashRouter>
组件,这部分学的不是很精细,官方文档内容好多啊,希望有大佬可以指点,这里附上我的路由内容
import { Navigate, useRoutes } from 'react-router-dom'
import MyLayout from '../pages/myLayout/myLayout'
import Login from '../pages/login/login'
import Order from '../pages/order/order'
import SiteOrder from '../pages/siteOrder/siteOrder'
import PutStore from '../pages/putStore/putStore'
const GetRouters = () => {
const routes = useRoutes([
{
path: '/',
element: (
<Navigate
to={localStorage.getItem('token') ? 'layout' : 'login'}></Navigate>
),
},
{
path: '/layout',
element: <MyLayout />,
children: [
{
path: 'order',
element: <Order></Order>,
index: true,
},
{
path: 'siteOrder',
element: <SiteOrder></SiteOrder>,
},
{
path: 'putOrder',
element: <PutStore></PutStore>,
},
],
},
{
path: '/login',
element: <Login></Login>,
},
])
return routes
}
export default GetRouters
在app.jsx中导入并使用
import React from 'react'
import './App.css'
import GetRouters from './router/routes'
import { HashRouter } from 'react-router-dom'
import './index.css'
const App = () => {
return (
<HashRouter>
<GetRouters />
</HashRouter>
)
}
export default App
路由守卫值得我再次研究下,以后专门写一篇吧。
antd样式修改
antd官网
写的过程中发现,样式修改本地是生效的,但是打包放线上就不生效了,有些组件可以直接传className进行修改,有些不能的,我就只能复制浏览器控制台的类名进行修改了,例如这样,感觉十分麻烦,但是写的时候又没有找到更好的方法,希望大佬们赐教。
:where(.css-dev-only-do-not-override-kghr11).ant-collapse
> .ant-collapse-item
> .ant-collapse-header {
align-items: center;
}
axios
axios官网
这个我没有自己封装,网上找了别人的代码直接用的,但是找不到出处了,这次和我对接的后端只用了post请求,所以我也只改了一部分,请求头和数据返回的码都可以根据自己需求修改
/**
* 网络请求配置
*/
import { message } from 'antd';
import { BASE_URL, TIMEOUT } from "./config";
import axios from "axios";
axios.defaults.timeout = TIMEOUT;
axios.defaults.baseURL = BASE_URL;
/**
* http request 拦截器
*/
axios.interceptors.request.use(
(config) => {
config.data = JSON.stringify(config.data);
config.headers = {
"Content-Type": "application/json",
"token": localStorage.getItem('token') || ''
};
return config;
},
(error) => {
return Promise.reject(error);
}
);
/**
* http response 拦截器
*/
axios.interceptors.response.use(
(response) => {
if (response.data.errCode === 2) {
console.log("过期");
}
if (response.data.code === 200) {
return response;
} else {
console.log('====', response.data)
message.error(response.data.msg)
}
console.log(response)
},
(error) => {
console.log("请求出错:", error);
message.error(error.response.data.msg)
}
);
/**
* 封装get方法
* @param url 请求url
* @param params 请求参数
* @returns {Promise}
*/
export function get (url, params = {}) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params,
}).then((response) => {
landing(url, params, response.data);
resolve(response.data);
})
.catch((error) => {
reject(error);
});
});
}
/**
* 封装post请求
* @param url
* @param data
* @returns {Promise}
*/
export function post (url, data) {
return new Promise((resolve, reject) => {
axios.post(url, data).then(
(response) => {
//关闭进度条
resolve(response?.data);
},
(err) => {
reject(err);
}
);
});
}
/**
* 封装patch请求
* @param url
* @param data
* @returns {Promise}
*/
export function patch (url, data = {}) {
return new Promise((resolve, reject) => {
axios.patch(url, data).then(
(response) => {
resolve(response.data);
},
(err) => {
msag(err);
reject(err);
}
);
});
}
/**
* 封装put请求
* @param url
* @param data
* @returns {Promise}
*/
export function put (url, data = {}) {
return new Promise((resolve, reject) => {
axios.put(url, data).then(
(response) => {
resolve(response.data);
},
(err) => {
msag(err);
reject(err);
}
);
});
}
//统一接口处理,返回数据
export default function (fecth, url, param) {
let _data = "";
return new Promise((resolve, reject) => {
switch (fecth) {
case "get":
console.log("begin a get request,and url:", url);
get(url, param)
.then(function (response) {
resolve(response);
})
.catch(function (error) {
console.log("get request GET failed.", error);
reject(error);
});
break;
case "post":
post(url, param)
.then(function (response) {
resolve(response);
})
.catch(function (error) {
console.log("get request POST failed.", error);
reject(error);
});
break;
default:
break;
}
});
}
//失败提示
function msag (err) {
if (err && err.response) {
switch (err.response.status) {
case 400:
alert(err.response.data.error.details);
break;
case 401:
alert("未授权,请登录");
break;
case 403:
alert("拒绝访问");
break;
case 404:
alert("请求地址出错");
break;
case 408:
alert("请求超时");
break;
case 500:
alert("服务器内部错误");
break;
case 501:
alert("服务未实现");
break;
case 502:
alert("网关错误");
break;
case 503:
alert("服务不可用");
break;
case 504:
alert("网关超时");
break;
case 505:
alert("HTTP版本不受支持");
break;
default:
}
}
}
/**
* 查看返回的数据
* @param url
* @param params
* @param data
*/
function landing (url, params, data) {
if (data.code === -1) {
}
}
使用方法:可以自己再建一个文件夹,如api.js
import { post } from "../utils/request"
// 用户登录
export const userLogin = (data) => {
return post('/kitchen/user/login', data)
}
在页面中使用
const login = () => {
userLogin({
mobile: mobile,
password: password,
}).then((res) => {
if (res.code == 200) {
localStorage.setItem('token', res.data.kitcheninfo.token)
localStorage.setItem('nickname', res.data.kitcheninfo.nickname)
navigate('/layout/order')
}
})
}
这个就根据自己的风格了,想怎么写就怎么写,可以用链式写法,不喜欢的也可以采用async await的写法。
Hooks
hooks文档
个人比较喜欢函数式组件,类组件有点复杂,而且我不太喜欢this,使用函数式组件就可以不用this了哈哈哈哈,钩子也有很多,我也不是全部熟悉,这里用的多的有useState,useEffect
。
useState用法:
const [mobile, setMobile] = useState('')
const handleMobileChange = (val) => {
setMobile(val.target.value)
}
useEffect用法:
useEffect(() => {
getTopNumber()
}, [])
建议大家还是先熟悉一个框架再拿来用,不然影响开发效率,小一点的项目可以拿来练手,大一点的项目还是慎重考虑吧,别写着写着发现有东西改不动了,就很烦。
vite
vite官网
真是惭愧,vite我也不熟悉,但是用了,使用vite写了有两个项目,一个vue,一个react,vue的比较大一点,使用起来就感觉启动项目非常快,最起码比webpack快,两者也是各有优势,大家感兴趣的话可以自行了解一下,上线了可以进行一些配置隐藏自己的控制台输出和网络请求。