1. React 18 极客园项目实战:从零搭建企业级后台管理系统
作为一名长期奋战在一线的前端开发者,我深知掌握React生态对企业级应用开发的重要性。今天我将通过"极客园"这个实战项目,带你完整走一遍React 18 + Ant Design + Redux Toolkit的技术栈组合开发流程。这个项目不仅包含了基础框架搭建,还涉及路由配置、状态管理、权限控制等核心功能,最后我们会得到一个具备完整登录体系和后台管理界面的SPA应用。
提示:本文假设你已经具备基本的React和JavaScript知识,如果你是完全的新手,建议先学习React官方文档的基础部分。
2. 项目初始化与环境配置
2.1 使用Create React App创建项目
现代React项目开发的首选工具仍然是Create React App(CRA),它提供了零配置的项目脚手架。我们使用以下命令创建项目:
bash复制npx create-react-app react-jike --template typescript
这里我推荐加上--template typescript参数,因为TypeScript能为大型项目提供更好的类型安全。不过为了与教程保持一致,我们先使用JavaScript版本。
创建完成后,进入项目目录并启动开发服务器:
bash复制cd react-jike
npm start
2.2 项目结构优化与清理
初始化的CRA项目包含许多我们不需要的样板文件和代码。按照企业级项目的标准,我们需要进行以下清理:
- 删除
src目录下所有文件,只保留index.js - 创建以下目录结构:
code复制src/ ├── assets/ # 静态资源 ├── components/ # 公共组件 ├── pages/ # 页面组件 ├── router/ # 路由配置 ├── store/ # 状态管理 ├── utils/ # 工具函数 ├── App.js # 根组件 └── index.js # 入口文件
清理后的index.js保持最简形式:
jsx复制import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
App.js也简化为:
jsx复制function App() {
return (
<div className="App">
this is my app
</div>
);
}
export default App;
3. 核心依赖安装与配置
3.1 样式预处理:Sass安装
虽然CRA支持CSS out of the box,但Sass提供的嵌套、变量等特性能让我们的样式更易维护:
bash复制npm install sass -D
安装后,我们可以创建.scss文件并使用Sass的所有功能。
3.2 Ant Design组件库集成
Ant Design是阿里开源的企业级UI组件库,特别适合后台管理系统开发:
bash复制npm install antd
在项目中引入Button组件测试:
jsx复制import { Button } from "antd";
function App() {
return (
<div className="App">
this is my app <Button type="primary">test</Button>
</div>
);
}
注意:Ant Design 5.x版本采用了CSS-in-JS方案,按需加载样式,不需要再额外引入CSS文件。
3.3 路由系统配置
我们使用React Router v6作为路由解决方案:
bash复制npm install react-router-dom
创建基础路由配置src/router/index.js:
jsx复制import { createBrowserRouter } from 'react-router-dom'
import Layout from '../pages/Layout'
import Login from '../pages/Login'
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
},
{
path: "/login",
element: <Login />,
},
]);
export default router;
然后在入口文件中使用路由:
jsx复制import { RouterProvider } from 'react-router-dom';
import router from './router';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
4. 高级配置与开发效率优化
4.1 路径别名配置
随着项目规模增长,相对路径(如../../../components/Button)会变得难以维护。我们可以通过CRACO(Create React App Configuration Override)来配置路径别名。
首先安装CRACO:
bash复制npm install @craco/craco -D
创建craco.config.js:
js复制const path = require("path");
module.exports = {
webpack: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
};
然后修改package.json中的scripts:
json复制"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
}
为了让编辑器(如VSCode)能识别路径别名,我们还需要创建jsconfig.json:
json复制{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
}
}
现在我们可以使用@/components/Button这样的绝对路径导入了。
4.2 代码版本控制
良好的Git实践对团队协作至关重要。我们初始化Git仓库并推送到远程:
bash复制git init
git add .
git commit -m "initial project setup"
git remote add origin https://gitee.com/yourname/react-jike.git
git push -u origin master
对于实际开发,我们更应该使用分支工作流:
bash复制# 创建并切换到dev分支
git checkout -b dev
# 推送到远程dev分支
git push -u origin dev
后续开发都在dev分支进行,通过Pull Request合并到master分支。
5. 登录功能实现
5.1 登录页面基础搭建
创建src/pages/Login/index.js和对应的样式文件:
jsx复制import './index.scss'
import { Card, Form, Input, Button } from 'antd'
import logo from '@/assets/logo.png'
const Login = () => {
return (
<div className="login">
<Card className="login-container">
<img className="login-logo" src={logo} alt="" />
<Form>
<Form.Item>
<Input size="large" placeholder="请输入手机号" />
</Form.Item>
<Form.Item>
<Input size="large" placeholder="请输入验证码" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" size="large" block>
登录
</Button>
</Form.Item>
</Form>
</Card>
</div>
)
}
export default Login
样式文件index.scss:
scss复制.login {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background: center/cover url('~@/assets/login.png');
.login-logo {
width: 200px;
height: 60px;
display: block;
margin: 0 auto 20px;
}
.login-container {
width: 440px;
height: 360px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 50px rgb(0 0 0 / 10%);
}
}
5.2 表单验证实现
Ant Design的Form组件内置了强大的验证功能。我们为手机号和验证码添加验证规则:
jsx复制<Form validateTrigger={['onBlur']}>
<Form.Item
name="mobile"
rules={[
{ required: true, message: '请输入手机号' },
{
pattern: /^1[3-9]\d{9}$/,
message: '手机号码格式不对'
}
]}
>
<Input size="large" placeholder="请输入手机号" />
</Form.Item>
<Form.Item
name="code"
rules={[
{ required: true, message: '请输入验证码' },
]}
>
<Input size="large" placeholder="请输入验证码" maxLength={6} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" size="large" block>
登录
</Button>
</Form.Item>
</Form>
这里我们设置了validateTrigger为onBlur,表示在失去焦点时触发验证。手机号验证使用了正则表达式确保格式正确。
5.3 表单提交与数据处理
我们需要处理表单提交事件并获取用户输入的数据:
jsx复制const onFinish = (values) => {
console.log('表单数据:', values);
// 这里将添加登录逻辑
};
<Form
validateTrigger={['onBlur']}
onFinish={onFinish}
>
{/* 表单项 */}
</Form>
6. 状态管理与Redux集成
6.1 Redux Toolkit配置
Redux Toolkit是官方推荐的Redux最佳实践工具集,能大幅简化Redux代码:
bash复制npm install @reduxjs/toolkit react-redux
创建store配置src/store/index.js:
js复制import { configureStore } from '@reduxjs/toolkit'
import userReducer from './modules/user'
export default configureStore({
reducer: {
user: userReducer
}
})
创建用户模块src/store/modules/user.js:
js复制import { createSlice } from '@reduxjs/toolkit'
import { request } from '@/utils'
const userStore = createSlice({
name: 'user',
initialState: {
token: ''
},
reducers: {
setToken(state, action) {
state.token = action.payload
}
}
})
const { setToken } = userStore.actions
const userReducer = userStore.reducer
const fetchLogin = (loginForm) => {
return async (dispatch) => {
const res = await request.post('/authorizations', loginForm)
dispatch(setToken(res.data.token))
}
}
export { fetchLogin }
export default userReducer
6.2 请求模块封装
我们使用axios作为HTTP客户端,并封装请求拦截器:
src/utils/request.js:
js复制import axios from 'axios'
const request = axios.create({
baseURL: 'http://geek.itheima.net/v1_0',
timeout: 5000
})
request.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
})
request.interceptors.response.use(response => {
return response.data
}, error => {
return Promise.reject(error)
})
export { request }
6.3 登录功能完整实现
现在我们可以完善登录功能,将表单数据提交到Redux action:
jsx复制import { useDispatch } from 'react-redux'
import { fetchLogin } from '@/store/modules/user'
import { message } from 'antd'
import { useNavigate } from 'react-router-dom'
const Login = () => {
const dispatch = useDispatch()
const navigate = useNavigate()
const onFinish = async (values) => {
try {
await dispatch(fetchLogin(values)).unwrap()
navigate('/')
message.success('登录成功')
} catch (e) {
message.error(e.response?.data?.message || '登录失败')
}
}
// ... 表单JSX
}
7. 权限控制与路由守卫
7.1 Token持久化存储
为了在页面刷新后保持登录状态,我们需要将token存入localStorage:
js复制// src/utils/token.js
const TOKEN_KEY = 'geek_pc_token'
export const setToken = (token) => localStorage.setItem(TOKEN_KEY, token)
export const getToken = () => localStorage.getItem(TOKEN_KEY)
export const clearToken = () => localStorage.removeItem(TOKEN_KEY)
修改user slice使用持久化token:
js复制import { getToken, setToken } from '@/utils/token'
const userStore = createSlice({
name: 'user',
initialState: {
token: getToken() || ''
},
reducers: {
setToken(state, action) {
state.token = action.payload
setToken(action.payload)
}
}
})
7.2 路由权限控制
创建高阶组件src/components/AuthRoute.js:
jsx复制import { getToken } from '@/utils/token'
import { Navigate } from 'react-router-dom'
const AuthRoute = ({ children }) => {
const token = getToken()
return token ? children : <Navigate to="/login" replace />
}
export default AuthRoute
在路由配置中使用:
jsx复制const router = createBrowserRouter([
{
path: "/",
element: (
<AuthRoute>
<Layout />
</AuthRoute>
),
},
{
path: "/login",
element: <Login />,
},
])
7.3 请求拦截器注入Token
修改请求拦截器,自动在请求头中添加Token:
js复制request.interceptors.request.use(config => {
const token = getToken()
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}, error => {
return Promise.reject(error)
})
8. 后台布局与二级路由
8.1 基础布局结构
创建src/pages/Layout/index.js:
jsx复制import { Layout, Menu, Popconfirm } from 'antd'
import {
HomeOutlined,
DiffOutlined,
EditOutlined,
LogoutOutlined,
} from '@ant-design/icons'
import './index.scss'
import { Outlet, useNavigate, useLocation } from 'react-router-dom'
const { Header, Sider } = Layout
const items = [
{
label: '首页',
key: '/',
icon: <HomeOutlined />,
},
{
label: '文章管理',
key: '/article',
icon: <DiffOutlined />,
},
{
label: '创建文章',
key: '/publish',
icon: <EditOutlined />,
},
]
const GeekLayout = () => {
const navigate = useNavigate()
const location = useLocation()
const onMenuClick = ({ key }) => {
navigate(key)
}
return (
<Layout>
<Header className="header">
<div className="logo" />
<div className="user-info">
<span className="user-name">用户名</span>
<span className="user-logout">
<Popconfirm title="是否确认退出?" okText="退出" cancelText="取消">
<LogoutOutlined /> 退出
</Popconfirm>
</span>
</div>
</Header>
<Layout>
<Sider width={200} className="site-layout-background">
<Menu
mode="inline"
theme="dark"
items={items}
onClick={onMenuClick}
selectedKeys={[location.pathname]}
style={{ height: '100%', borderRight: 0 }}
/>
</Sider>
<Layout className="layout-content" style={{ padding: 20 }}>
<Outlet />
</Layout>
</Layout>
</Layout>
)
}
export default GeekLayout
8.2 二级路由配置
修改路由配置,添加嵌套路由:
jsx复制const router = createBrowserRouter([
{
path: '/',
element: (
<AuthRoute>
<Layout />
</AuthRoute>
),
children: [
{
index: true,
element: <Home />,
},
{
path: 'article',
element: <Article />,
},
{
path: 'publish',
element: <Publish />,
},
],
},
{
path: '/login',
element: <Login />,
},
])
8.3 全局样式优化
添加normalize.css重置浏览器默认样式:
bash复制npm install normalize.css
在入口文件引入:
jsx复制import 'normalize.css'
import './index.scss'
调整全局样式index.scss:
scss复制html, body {
margin: 0;
height: 100%;
}
#root {
height: 100%;
}
.ant-layout {
height: 100%;
}
.layout-content {
overflow-y: auto;
}
9. 项目总结与扩展思考
通过这个项目,我们完整实现了:
- React 18基础项目搭建
- Ant Design组件库集成
- React Router v6路由配置
- Redux Toolkit状态管理
- 完整的登录鉴权流程
- 响应式后台布局
在实际企业开发中,还可以进一步优化:
- 添加多环境配置(开发、测试、生产)
- 实现动态路由和权限菜单
- 集成国际化解决方案
- 添加错误边界和全局异常处理
- 性能优化(代码分割、懒加载等)
这个项目骨架已经包含了企业级React应用的核心要素,你可以基于此继续扩展功能模块。我在实际开发中发现,良好的项目结构和规范的代码组织能显著提高团队协作效率,这也是我在本文中特别强调的一点。