前言:学习react有一段时间了 始终感觉vite+react更舒服一点 但是奈何vite搭配react的各种插件包和脚手架有点差异 虽然vite方面也配置好了 但是感觉市场上 react脚手架似乎应用的更多一点,那就做下脚手架的笔记吧!
进入正题
1. node自带的npx 不用管
npx create-react-app xxx
2.初始化一下 在启动看下
npm i
npm start
3.开始下载插件的依赖了
npm i axios react-router-dom redux react-redux @reduxjs/toolkit
4.下载 less 或者sass预处理器 这里最好放在开发环境 打包后都是css
npm i sass -D
5.先配置 react-router-don路由
1.在src里面创建个router文件夹 再在里面创建index.js
2.在这个index文件里 copy吧 改自己想要的效果 图二是路由懒加载 嫌麻烦就用图1
import {createBrowserRouter} from 'react-router-dom';
import XXX from '@/xxx/xxx'
// 创建路由表 这里没直接暴露出去 而是这样写 因为ESlint。。。
export const router = createBrowserRouter([
{
path: '/',
element: <div>等</div>,
},
{
path: '/home',
element: <div>home</div>,
},
{
path: '/sub',
element: <div>Sub</div>,
},
{
path: '/xxx',
element: <XXX >xxx</XXX >,
},
])
import {createBrowserRouter} from 'react-router-dom';
import { lazy } from 'react';
// import Home from '../view/Home/Home'
// import Login from '../view/Login/Login'
const Home = lazy(() => import('../view/Home/Home'));
const Login = lazy(() => import('../view/Login/Login'));
// 创建路由表
export const router = createBrowserRouter([
{
path: '/',
element: <div>等</div>,
},
{
path: '/home',
element: <Home>home</Home>,
},
{
path: '/login',
element: <Login>Login</Login>,
},
])
3,然后就是在src根文件index.js引入就完了 (这里连App.js都不需要了~)
import React from "react";
import ReactDOM from "react-dom/client";
import { router } from "./router";
// 通过路由渲染跟路由
import { RouterProvider } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
// <React.StrictMode> 这玩意是 【严格模式】StrictMode 会引发的组件重复执行 可以注掉的 !!!
<RouterProvider router={router}></RouterProvider>
// </React.StrictMode>
);
4.这一步看个人喜好 改不改看自己 可忽略这一步
1.找到依赖node_modules里面的react-script里的webpack.config.js文件搜索alias配置项 添加下面代码后再重新启动项目npm start
alias: {
"@":path.resolve('src'),
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
},
2.配置代理 项目上线的时候是不需要的 这里看项目开发 具体情况再做调整
npm i http-proxy-middleware -D
在src目录里面生成一个setupProxy.js文件
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
createProxyMiddleware("/api", {
target: "http://localhost:8080", // 这里看后端给你协议.域名.端口是多少就改成多少就行了
changeOrigin: true, // 控制服务器接收 到的请求头中host字段的值
pathRewrite: {'^/api':''} // 去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
}),
);
};
6.接下来引入Ant Design UI组件库
1.下载ant包
npm install antd
2.修改 app.js,引入 antd 的样式 组件中需要什么组件就引入(按需加载,这里我就更喜欢vite的配置了。。。)
import 'antd/dist/reset.css';
举个例子
import { Button } from 'antd';
export default function Home() {
return (
<div>Home
<Button type="primary">点我</Button>
</div>
)
}
3.重置默认样式 (可用自己的 也可用这里的)
html {
color: #000;
overflow-y: scroll;
overflow: -moz-scrollbars
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td {
margin: 0;
padding: 0
}
body,button,input,select,textarea {
font: 12px arial
}
h1,h2,h3,h4,h5,h6 {
font-size: 100%
}
em {
font-style: normal
}
small {
font-size: 12px
}
ul,ol {
list-style: none
}
a {
text-decoration: none
}
a:hover {
text-decoration: underline
}
fieldset,img {
border: 0
}
button,input,select,textarea {
font-size: 100%
}
table {
border-collapse: collapse;
border-spacing: 0
}
img {
-ms-interpolation-mode: bicubic
}
textarea {
resize: vertical
}
7.然后就是配置数据仓库了
1.在src目录里创建store目录 接着store里创建index.js
import {configureStore} from '@reduxjs/toolkit';
import useUserStore from './userinfoStore'
// 创建仓库并且暴露
export const store = configureStore({
reducer:{
useUserStore,
}
})
2.下面的代码是userinfoStore.js
import {createSlice} from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'useUserStore',
initialState:{
userInfo:1
},
reducers: {
incremented(state,{value}){
state.userInfo = value;
},
increment(state,val) {
state.value++
},
decrement(state,val) {
state.value--
},
incrementByAmount(state, action) {
state.value += action.payload
},
},
})
// export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
3.再将store引入index.js中
import React from "react";
import ReactDOM from "react-dom/client";
import { router } from "./router";
// 通过路由渲染跟路由
import { RouterProvider } from "react-router-dom";
import {store} from "./store";
import { Provider } from "react-redux";
import "antd/dist/reset.css";
import "./index.css";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
// <React.StrictMode> 这玩意是 【严格模式】StrictMode 会引发的组件重复执行 可以注掉的 !!!
<Provider store={store}>
<RouterProvider router={router}></RouterProvider>
</Provider>
// </React.StrictMode>
);
4.接下来咋们看看试用例子
home组件中使用数据仓库
import {useDispatch,useSelector} from 'react-redux';
import {Button} from 'antd'
export default function Login() {
const dispatch = useDispatch()
const user = useSelector((state)=>{
return state.useUserStore.userInfo;
});
const users = (str='mm')=>{
console.log(str,'str');
// type 仓库名称/方法 参数
dispatch({type:'useUserStore/incremented',value:100})
}
return (
<div>Login -- {user}
<Button onClick={users.bind(null,undefined)} type='primary'>点我赋值</Button>
</div>
)
}
8.最后配置axios的二次封装了
1.在src目录下创建required或者utils文件夹 再在里面创建request.js 我这里上面做了配置代理 所以这里baseURL注了 当项目上线还是得用这里的baseURL的 下面还有请求拦截和响应拦截 自己看业务需求来补就行了 用不着 errorCode 的可以自己注了 或者 自己写点json数据补就行了
import axios from "axios";
import errorCode from "@/utils/errorCode";
//设置默认请求头
axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
// const BaseURL = "api";
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
// baseURL:
// process.env.NODE_ENV === "production"
// ? `/`
// : `http://dev.ktpark.net:9000/`, // 请求地址的基准路径
/* http:"dev.ak.com"
https:"pay.ak.com" */
// 超时
timeout: 3000, //请求超时时间(5秒后还未接收到数据,就需要再次发送请求)
// retry: 1, //设置全局重试请求次数(最多重试几次请求)
// retryDelay: 100, //设置全局请求间隔
});
// // 添加请求拦截器
// service.interceptors.request.use(config => {
// // 在发送请求之前做些什么
//
// return config
// }, error => {
// // 对请求错误做些什么
// return Promise.reject(error)
// })
// 响应拦截器
service.interceptors.response.use(
(response) => {
console.log(response,'response');
// const code = response.data.code || 200;
const code = response.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || response.data.msg || errorCode["default"];
// 当返回不对劲错误信息 直接发送错误提示
if (response.status === 200 && response.data?.data?.scanCode === -1) {
return Promise.reject("error");
}
if (response.status === 500) {
return Promise.reject(new Error(msg));
} else if (response.status !== 200) {
return Promise.reject("error");
} else if (response.status === 200 && response.data?.code === -1) {
return Promise.reject("error");
} else {
return response.data;
}
},
(error) => {
return Promise.reject(error);
}
);
export default service;
2.下面随便来点errorCode 的json数据
const errorCode = {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'404': '访问资源不存在',
'500': '终端不在线',
'default': '系统未知错误,请反馈给管理员'
}
export default errorCode;
3. 最后编写接口了!接口封装的方法非常多 但是我比较喜欢这种简单明了的风格的接口的
import getMSg from './index'
// 这里一定要看 注释啊! 上面引入的是刚才编写的axios拦截封装啊 一定要看啊 不能傻逼一样说看不
// 懂!!!
// 默认地址
let pathUrl = '/api'
let wangyi = '/qqq'
// 上面两个变量看自己 看业务需求 有的后端和蔼可亲 不会搞这些多端对接 但是有时候总会避免不了这
// 种情况 对不对?
export const getmmsg = (params)=>{
console.log(params,'params');
// 上面的日志是可以注掉的 这里我只是为了方便调接口 查看是否有误
return getMSg({
method:'get',
url:wangyi+'/xxx/xxx',
params
})
}
export const postmmsg = (data)=>{
return getMSg({
method:'GET',
url:pathUrl+'/ad/info',
data
})
}
4.调接口方面我就不写demo了 不能饭喂到嘴里对吧 hha 感谢曾经的leader那么耐心的带我~