完整结构
1. 项目结构设置
首先创建项目:
npm create vite@latest . --template react
cd .
npm install
2. 设置Docker中的MySQL
创建docker-compose.yml
文件(与之前相同):
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql_container
environment:
MYSQL_ROOT_PASSWORD: yourpassword
MYSQL_DATABASE: testdb
MYSQL_USER: user
MYSQL_PASSWORD: password
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
启动MySQL容器:
docker-compose up -d
3. 创建后端API
在项目根目录下创建backend文件夹并初始化:
mkdir backend
cd backend
npm init -y
npm install express mysql2 cors
创建后端服务器文件:
const express = require('express');
const mysql = require('mysql2');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
// 创建数据库连接
const connection = mysql.createConnection({
host: 'localhost',
user: 'user',
password: 'password',
database: 'testdb'
});
// 测试数据库连接
connection.connect((err) => {
if (err) {
console.error('数据库连接失败: ' + err.stack);
return;
}
console.log('数据库连接成功');
});
// 创建测试表
connection.query(`
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL
)
`, (err) => {
if (err) throw err;
console.log('用户表创建成功');
});
// API端点
app.get('/api/users', (req, res) => {
connection.query('SELECT * FROM users', (err, results) => {
if (err) {
res.status(500).json({ error: err.message });
return;
}
res.json(results);
});
});
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
connection.query('INSERT INTO users (name, email) VALUES (?, ?)',
[name, email],
(err, results) => {
if (err) {
res.status(500).json({ error: err.message });
return;
}
res.json({ id: results.insertId, name, email });
}
);
});
const PORT = 5000;
app.listen(PORT, () => {
console.log(`服务器运行在端口 ${PORT}`);
});
4. 修改React前端代码
安装必要的依赖:
npm install axios
修改src/App.jsx
文件:
import { useState, useEffect } from 'react'
import axios from 'axios'
import './App.css'
function App() {
const [users, setUsers] = useState([])
const [newUser, setNewUser] = useState({ name: '', email: '' })
useEffect(() => {
fetchUsers()
}, [])
const fetchUsers = async () => {
try {
const response = await axios.get('http://localhost:5000/api/users')
setUsers(response.data)
} catch (error) {
console.error('获取用户失败:', error)
}
}
const handleSubmit = async (e) => {
e.preventDefault()
try {
await axios.post('http://localhost:5000/api/users', newUser)
setNewUser({ name: '', email: '' })
fetchUsers()
} catch (error) {
console.error('添加用户失败:', error)
}
}
return (
<div className="container">
<h1>用户管理系统</h1>
<form onSubmit={handleSubmit} className="form">
<input
type="text"
placeholder="姓名"
value={newUser.name}
onChange={(e) => setNewUser({ ...newUser, name: e.target.value })}
/>
<input
type="email"
placeholder="邮箱"
value={newUser.email}
onChange={(e) => setNewUser({ ...newUser, email: e.target.value })}
/>
<button type="submit">添加用户</button>
</form>
<h2>用户列表</h2>
<ul className="user-list">
{users.map(user => (
<li key={user.id}>
{user.name} - {user.email}
</li>
))}
</ul>
</div>
)
}
export default App
更新src/App.css
添加一些基本样式:
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.form {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 8px 16px;
background-color: #646cff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #747bff;
}
.user-list {
list-style: none;
padding: 0;
}
.user-list li {
padding: 10px;
border-bottom: 1px solid #eee;
}
5. 运行应用
- 启动后端服务器:
cd backend
node server.js
- 在新的终端中启动Vite开发服务器:
npm run dev