视频演示:
https://www.bilibili.com/video/BV1La4y1a7Rp/
工程概述:
- 前后端分离,进行简单增查改删(CRUD)
- 前端使用React
- 后端使用Spring Data JPA
- 数据库使用MySQL
后台端代码上一节已经展示,这里将不再重复,仅展示React代码既可。
往期内容
# | 内容 |
---|---|
01 | Vue+Spring Boot JPA+MySQL 增查改删 |
02 | Thymeleaf+Spring Boot JPA+MySQL 增查改删 |
03 | Vue+Spring Boot 文件操作,上传、预览和删除 |
04 | Thymeleaf+Spring Boot 文件操作,上传、预览和删除 |
#EmployeeService.js
import http from "../http-common";
class EmployeeService {
getAll(pageNumber) {
return http.get(`/employee?page=${pageNumber}`);
}
get(id) {
return http.get(`/employee/${id}`);
}
create(data) {
return http.post("/employee", data);
}
update(data) {
return http.put("/employee", data);
}
delete(id) {
return http.delete(`/employee/${id}`);
}
}
export default new EmployeeService();
#EmployeesCreateComponent.js
import React, { Component } from "react";
import { Redirect } from "react-router-dom";
import EmployeeService from "../services/EmployeeService";
export default class EmployeesCreateComponent extends Component {
constructor(props) {
super(props);
this.saveEmployee = this.saveEmployee.bind(this);
this.onChangeName = this.onChangeName.bind(this);
this.onChangeGender = this.onChangeGender.bind(this);
this.onChangeAge = this.onChangeAge.bind(this);
this.onChangeIntroduce = this.onChangeIntroduce.bind(this);
this.state = {
id: null,
name: "",
gender: "MALE",
age: 18,
introduce: "",
ageRange: [],
redirect: false
};
}
componentDidMount() {
//初始化年龄下拉列表
var rows = [], i = 17, len = 60;
while (++i <= len) rows.push(i);
this.setState({
ageRange : rows
})
}
onChangeName(e) {
this.setState({
name: e.target.value
});
}
onChangeGender(e) {
this.setState({
gender: e.target.value
});
}
onChangeAge(e){
this.setState({
age: e.target.value
});
}
onChangeIntroduce(e){
this.setState({
introduce: e.target.value
});
}
//保存
saveEmployee() {
var data = {
name: this.state.name,
gender: this.state.gender,
age: this.state.age,
introduce: this.state.introduce
};
EmployeeService.create(data)
.then(response => {
this.setState({
redirect: true
});
})
.catch(e => {
console.log(e);
});
}
render() {
const { redirect } = this.state;
return (
<div className="submit-form">
{redirect ? (
<Redirect to='/employees'/>
) : (
<div>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
type="text"
className="form-control"
id="name"
required
value={this.state.name}
onChange={this.onChangeName}
name="name"
/>
</div>
<div className="form-group">
<input
type="radio"
id="male"
name="gender"
value="MALE"
onChange={this.onChangeGender}
/>
<label htmlFor="male">Male</label>
<input
type="radio"
id="female"
name="gender"
value="FEMALE"
onChange={this.onChangeGender}
/>
<label htmlFor="female">Female</label>
<div className="form-group">
<label> Age:</label>
<select className="form-control" value={this.state.age} name="age" onChange={this.onChangeAge}>
{this.state.ageRange.map((a, index) => (
<option value={a} key={index}>{a}</option>
))}
</select>
</div>
<div className="form-group">
<label> Introduce:</label>
<textarea className="form-control" value={this.state.introduce} name="introduce" onChange={this.onChangeIntroduce} ></textarea>
</div>
</div>
<button onClick={this.saveEmployee} className="btn btn-success">
Add Employee
</button>
</div>
)}
</div>
);
}
}
#EmployeesEditComponent.js
import React, { Component } from "react";
import EmployeesService from "../services/EmployeeService";
export default class Tutorial extends Component {
constructor(props) {
super(props);
this.getEmployee = this.getEmployee.bind(this);
this.onChangeName = this.onChangeName.bind(this);
this.onChangeGender = this.onChangeGender.bind(this);
this.onChangeAge = this.onChangeAge.bind(this);
this.onChangeIntroduce = this.onChangeIntroduce.bind(this);
this.updateEmployee = this.updateEmployee.bind(this);
this.state = {
currentEmployee: {
id: null,
name: "",
gender: "MALE",
age: 0,
introduce: ""
},
ageRange: []
};
}
componentDidMount() {
//初始化年龄列表
var rows = [], i = 17, len = 60;
while (++i <= len) rows.push(i);
this.setState({
ageRange : rows
})
//根据ID获取员工信息
this.getEmployee(this.props.match.params.id);
}
onChangeName(e) {
const name = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
name: name
}
};
});
}
onChangeGender(e) {
const gender = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
gender: gender
}
};
});
}
onChangeAge(e) {
const age = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
age: age
}
};
});
}
onChangeIntroduce(e) {
const introduce = e.target.value;
this.setState(function(prevState) {
return {
currentEmployee: {
...prevState.currentEmployee,
introduce: introduce
}
};
});
}
//根据ID获取员工信息
getEmployee(id) {
EmployeesService.get(id)
.then(response => {
this.setState({
currentEmployee: response.data.content
});
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
//更新员工信息
updateEmployee() {
EmployeesService.update(this.state.currentEmployee)
.then(response => {
console.log(response.data);
this.props.history.push('/employees');
})
.catch(e => {
console.log(e);
});
}
render() {
const { currentEmployee } = this.state;
return (
<div>
<div className="submit-form">
<form>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
type="text"
className="form-control"
id="name"
value={currentEmployee.name}
onChange={this.onChangeName}
/>
</div>
<div className="form-group">
<input
type="radio"
id="male"
name="gender"
checked={currentEmployee.gender === "MALE"}
value="MALE"
onChange={this.onChangeGender}
/>
<label htmlFor="male">Male</label>
<input
type="radio"
id="female"
name="gender"
checked={currentEmployee.gender === "FEMALE"}
value="FEMALE"
onChange={this.onChangeGender}
/>
<label htmlFor="female">Female</label>
<div className="form-group">
<label> Age:</label>
<select className="form-control" value={this.state.currentEmployee.age} name="age" onChange={this.onChangeAge}>
{this.state.ageRange.map((a, index) => (
<option value={a} key={index}>{a}</option>
))}
</select>
</div>
<div className="form-group">
<label> Introduce:</label>
<textarea className="form-control" value={this.state.currentEmployee.introduce} name="introduce" onChange={this.onChangeIntroduce} ></textarea>
</div>
</div>
</form>
<button
type="submit"
className="btn btn-success"
onClick={this.updateEmployee}
>
Update Employee
</button>
<p>{this.state.message}</p>
</div>
</div>
);
}
}
#EmployeesListComponent.js
import React, { Component } from "react";
import EmployeeService from '../services/EmployeeService';
import Pagination from "react-js-pagination";
import Table from 'react-bootstrap/Table';
import Button from 'react-bootstrap/Button';
export default class EmployeesListComponent extends Component {
constructor(props) {
super(props);
this.retrieveEmployee = this.retrieveEmployee.bind(this);
this.state = {
employees: [], //数据
activePage: 1, //默认首页
itemsCountPerPage: 3, //每页记录数
totalItemsCount: 0, //总记录数
pageRangeDisplayed: 5 //分页栏只显示5个分页
};
}
//点击分页
handlePageChange(activePage) {
this.setState({activePage: activePage});
this.retrieveEmployee(activePage);
}
componentDidMount() {
//获取首页
this.retrieveEmployee(1);
}
//根据ID删除员工
deleteEmployee(id){
EmployeeService.delete(id).then(response =>{
//删除成功后,也可以直接调用后台获取当前页面数据
this.retrieveEmployee(this.state.activePage);
});
}
//编辑页面
editEmployee(id) {
this.props.history.push('/employee/'+id)
}
//获取数据方法
retrieveEmployee(activePage) {
//前端页面从1开始,而后台页面从0开始,所以-1
EmployeeService.getAll(activePage-1)
.then(response => {
this.setState({
employees: response.data.content.content,
totalItemsCount: response.data.content.totalElements,
itemsCountPerPage: response.data.content.size
});
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
render() {
const { employees } = this.state;
return (
<div>
<Table striped bordered hover>
<thead >
<tr>
<th >ID</th>
<th >Name</th>
<th >Gender</th>
<th >Age</th>
<th >Introduce</th>
<th >Actions</th>
</tr>
</thead>
<tbody>
{employees && employees.map((tutorial, index) => (
<tr key={index}>
<td>{tutorial.id}</td>
<td>{tutorial.name}</td>
<td>{tutorial.gender}</td>
<td>{tutorial.age}</td>
<td>{tutorial.introduce}</td>
<td>
<Button variant="info" onClick={() => this.editEmployee(tutorial.id) }>编辑</Button>
<Button variant="danger" onClick={() => this.deleteEmployee(tutorial.id) }>删除</Button>
</td>
</tr>
))}
</tbody>
</Table>
{ this.state.totalItemsCount > 0 &&
<div className="col-md-6">
<Pagination
activePage={this.state.activePage}
itemsCountPerPage={this.state.itemsCountPerPage}
totalItemsCount={this.state.totalItemsCount}
pageRangeDisplayed={this.state.pageRangeDisplayed}
onChange={this.handlePageChange.bind(this)}
itemClass="page-item"
linkClass="page-link"
/>
</div>
}
</div>
);
}
}
本文使用 mdnice 排版