项目流程
项目安装
项目脚手架安装
npm create-react-app 项目名
#### 安装包
yarn add mobx mobx-react-lite
yarn add react-router-dom@6
yarn add sass
yarn add antd
yarn i @craco/craco@7.0.0-alpha.3 ### 修改别名路径、建议用这个,否则tailwindcss容易报错
yarn add -D @craco/craco ### 修改别名路径
yarn add axios
yarn add prop-types
### tailwindcss 相关
https://blog.csdn.net/qq_41999592/article/details/124245581 参考网站
yarn install -D tailwindcss@latest postcss@latest autoprefixer@latest
yarn add -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
npx tailwindcss-cli@latest init
### !!!注意
@tailwind base;
@tailwind components;
@tailwind utilities;
必须放在.css结尾的文件中引入,否则不生效!!!
### 文件说明
craco.config.js 修改别名路径
jsconfig.json 输入路径是提示路径
craco.config.js配置
const path = require('path')
module.exports = {
webpack: {
alias: {
'@': path.resolve(__dirname, 'src'), // 别名配置
// '@views': path.resolve(__dirname, 'src/views'),
},
},
devServer: {
proxy: { // 代理配置
'/': {
target: 'http://www.xxxx',
changeOrigin: true,
secure: false,
pathRewrite: {
'^/': '/'
}
}
},
},
style: {
postcssOptions: { // 样式文件配置
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
}
react-router-dom使用
注意⚠️:必须在函数式组件中使用
标签跳转
import { Link } from 'react-router-dom'
<Link to="/list">去列表页面</Link>
编程式导航
import { useNavigate } from 'react-router-dom'
export default function Index() {
const navigate = useNavigate()
const handlePath = () => {
navigate('/list', {replace: true}) // replace是否重定向浏览器地址
}
<div onClick={handlePath}></div>
}
store文件中使用mobx
import { makeAutoObservable } from 'mobx'
import { shopListApi } from '@/api'
class CommonData {
commonData = {
platList: [ ],
shopList: []
}
constructor() {
makeAutoObservable(this)
}
// 获取列表接口
getShopList = async () => {
let res = await shopListApi({page: 1, page_size: 100})
this.commonData.shopList = res.data.list.map(item => {
return {
name: item.shop_name,
id: item.id
}
})
}
}
export default CommonData
index.js页面
// 引入不同模块store
import {createContext, useContext} from "react";
import CommonData from "./common_data";
class RootStore {
constructor() {
this.commonDataStore = new CommonData()
}
}
const rootStore = new RootStore()
const context = createContext(rootStore)
const useStore = () => useContext(context)
export { useStore }
页面中使用useStore
// 注意必须在函数组件中才能使用!!!
import { observer } from 'mobx-react-lite' // 当store中数据修改 这里同步数据更新 否则数据不会更新
import { useStore } from '@/store'
function StoreList() {
const {
commonDataStore: { commonData },
} = useStore()
const list = commonData.shopList // list 就是commondata中数据
}
export default observer(StoreList)
使用antd + tailwindcss
index.js中引入 antd 和 tailwindcss样式
页面中使用
import { Button } from 'antd'
export default function Index() {
return (
<a className="mx-2 border text-red">编辑</a>
<Button type="link" danger> 删除 </Button>
)
}
打包优化- CDN配置
craco.config.js中配置webpack - cdn
const { whenProd, getPlugin, pluginByName } = require('@craco/craco')
module.exports = {
webpack: {
// 配置CDN 访问地址:https://cdnjs.com/
configure: (webpackConfig) => {
let cdn = {
js: [],
css: []
}
// 只有生产环境才配置
whenProd(() => {
// key: 不需要参与打包的具体包
// value: cdn文件中,挂载于全局的变量名称,为了替换之前在开发环境下通过import导入的react / react-dom
webpackConfig.externals = { // 打包后不会有react 和 react dom, 要使用 去index.html配置cdn使用
react: 'React',
'react-dom': 'ReactDOM'
}
cdn = {
js: [
'https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js'
],
css: []
}
})
// 为了在public/index.html注入cdn配置
const { isFound, match } = getPlugin(
webpackConfig,
pluginByName('HtmlWebpackPlugin')
)
if (isFound) {
// 找到了 HtmlWebpackPlugin
match.userOptions.cdn = cdn
}
return webpackConfig
}
},
}
同时在public/index.html引入cdn资源
<body>
<div id="root"></div>
<!-- root渲染完成后 加速第三方包的 CDN 链接 -->
<% htmlWebpackPlugin.options.cdn.js.forEach(cdnURL => { %>
<script src="<%= cdnURL %>"></script>
<% }) %>
</body>
react中路由懒加载
App.js文件修改
import { lazy, Suspense } from 'react'
修改成懒加载引入组件写法,比如:
const Login = lazy(() => import('@/views/Login/index.jsx'))
const NotFound = lazy(() => import('@/views/NotFound/index.jsx'))
routes外层用suspense包裹
<HashRouter className="App">
<Suspense fallback={
<div style={{textAlign: 'center', marginTop: 200}}>
{/* 路由还没加载完成之前,页面展示的内容 */}
加载中...
</div>
}>
<Routes>
{/* layout 需要鉴权处理 */}
<Route
path="/"
element={
<AuthRoute>
<Layout />
</AuthRoute>
}
>
{
routes.map((item, index) => {
return <Route key={index} {...item}></Route>
})
}
</Route>
<Route path="/login" element={<Login />}></Route>
<Route path="*" element={<NotFound />}></Route>
</Routes>
</Suspense>
</HashRouter>