创建一个 vue 项目
创建这个新的文件夹
创建前端项目 eggbox
数据库 SQL
CREATE DATABASE IF NOT EXISTS egg DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
USE egg;
CREATE TABLE `stu` (
`id` INT AUTO_INCREMENT, -- 自增主键
`name` VARCHAR(64) NOT NULL, -- 非空姓名字段,最大长度64字符
`stuid` INT DEFAULT NULL, -- 学号
`classroom` VARCHAR(10) DEFAULT NULL, -- 班级字段,最大长度10字符
`grade` DECIMAL(5, 2) DEFAULT NULL, -- 成绩字段,十进制数,最多5位数,小数点后2位
PRIMARY KEY (`id`) -- 设定t_id为主键
) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 使用InnoDB存储引擎,字符集设为utf8
设置表格为
创建后端项目
创建项目
设置项目
创建模块
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- Generated by https://start.springboot.io -->
<!-- 优质的 spring/boot/data/security/cloud 框架中文文档尽在 => https://springdoc.cn -->
<groupId>com.example</groupId>
<artifactId>eggBox</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eggBox</name>
<description>eggBox</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
.yml 配置
spring:
application:
name: eggBox
datasource:
url: jdbc:mysql://localhost:3306/egg?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
# 开启驼峰命名自动映射
map-underscore-to-camel-case: true
# 开启日志打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
type-aliases-package: com.baomidou.pojo
# 扫描mapper文件
mapper-locations: classpath:mapper/*.xml
mybatisplus 插件代码生成器
略.studyBox
中有详细的
代码
- controller
package com.example.eggbox.controller;
import com.example.eggbox.entity.Stu;
import com.example.eggbox.mapper.StuMapper;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author author
* @since 2024-05-22
*/
@RestController
@RequestMapping("/stu")
@CrossOrigin(origins = {"*", "null"})
public class StuController {
@Autowired
private StuMapper stuMapper;
private Gson gson=new Gson();
@GetMapping("/students")
public String getStudents(){
List<Stu> stu = stuMapper.selectList(null);
return gson.toJson(stu);
}
@PostMapping("/add")
public void addStudent(@RequestBody Stu stu){
stuMapper.insert(stu);
}
@PostMapping("delete")
public void removeStudent(@RequestBody Stu stu){
stuMapper.deleteById(stu);
}
@PostMapping("update")
public void updateStudent(@RequestBody Stu stu){
stuMapper.updateById(stu);
}
}
启动项目
前端增删改查
准备
vscode 打开之前创建的前端项目
新建一个终端
启动项目
安装 axios
引入 element-plus
npm install element-plus
安装 elementplus
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
安装 npm i [email protected]
将这些代码复制到 main.js
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'
App.vue 删成这样
启动项目
编写代码
复制这些代码
复制到这里
打开看一下
至此
- App.vue
<template>
<div id="app">
<table class="table caption-top">
<caption>
<h1>学生成绩管理系统</h1>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
</template>
<script>
export default {
}
</script>
<style>
</style>
去 elementplus 网站复制按钮组件
至此
- App.vue
<template>
<div id="app">
<table class="table caption-top">
<caption>
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</template>
<script>
import axios from "axios"
export default {
name: 'App',
components: {
},
methods:{
getStudent(){
axios({
url:"http://localhost:8080/stu/students",
method: 'GET',
}).then(res=>{
console.log(res.data);
})
}
}
}
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
</template>
<script>
export default {
}
</script>
<style>
</style>
至此
- App.vue
<template>
<div id="app">
<table class="table caption-top">
<caption>
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg></StudentEgg>
</tbody>
</table>
</div>
</template>
<script>
import axios from "axios"
import StudentEgg from './components/StudentEgg.vue'
export default {
name: 'App',
components: {
StudentEgg
},
methods:{
getStudent(){
axios({
url:"http://localhost:8080/stu/students",
method: 'GET',
}).then(res=>{
console.log(res.data);
})
}
}
}
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
<td>
<el-button type="primary" round>Primary</el-button>
<el-button type="primary" round>Primary</el-button>
</td>
</tr>
</template>
<script>
export default {
}
</script>
<style>
</style>
至此
- App.vue
<template>
<div id="app">
<table class="table caption-top">
<caption>
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg v-for="stu in students" :key="stu.id" :student="stu"></StudentEgg>
</tbody>
</table>
</div>
</template>
<script>
import axios from "axios"
import StudentEgg from './components/StudentEgg.vue'
export default {
name: 'App',
components: {
StudentEgg
},
data() {
return {
students:[]
}
},
methods:{
getStudent(){
axios({
url:"http://localhost:8080/stu/students",
method: 'GET',
}).then(res=>{
console.log(res.data);
this.students=res.data;
})
}
}
}
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<td>{{ student.name }}</td>
<td>{{ student.stuid }}</td>
<td>{{ student.classroom }}</td>
<td>{{ student.grade }}</td>
<td>
<el-button type="primary" round>Primary</el-button>
<el-button type="primary" round>Primary</el-button>
</td>
</tr>
</template>
<script>
export default {
props:["student"]
}
</script>
<style>
</style>
设置整个页面内容居中以及表格其他设置
至此
- App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg v-for="stu in students" :key="stu.id" :student="stu"></StudentEgg>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from "axios"
import StudentEgg from './components/StudentEgg.vue'
export default {
name: 'App',
components: {
StudentEgg
},
data() {
return {
students:[]
}
},
methods:{
getStudent(){
axios({
url:"http://localhost:8080/stu/students",
method: 'GET',
}).then(res=>{
console.log(res.data);
this.students=res.data;
})
}
}
}
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<td>{{ student.name }}</td>
<td>{{ student.stuid }}</td>
<td>{{ student.classroom }}</td>
<td>{{ student.grade }}</td>
<td>
<el-button type="primary" round>修改</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
export default {
props:["student"]
}
</script>
<style>
</style>
修改功能
点击“修改”按钮,表格信息会变成输入框,用户直接在输入框进行修改
先看效果:
至此,前端代码
- App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg v-for="stu in students" :key="stu.id" :student="stu"></StudentEgg>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from "axios"
import StudentEgg from './components/StudentEgg.vue'
export default {
name: 'App',
components: {
StudentEgg
},
data() {
return {
students:[]
}
},
methods:{
getStudent(){
axios({
url:"http://localhost:8080/stu/students",
method: 'GET',
}).then(res=>{
console.log(res.data);
this.students=res.data;
})
}
}
}
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round>删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
}
}
}
</script>
<style>
</style>
删除功能
演示:
点击删除后:
再刷新网页:
至此,前端代码:
- App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg v-for="stu in students" :key="stu.id" :student="stu"></StudentEgg>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from "axios"
import StudentEgg from './components/StudentEgg.vue'
export default {
name: 'App',
components: {
StudentEgg
},
data() {
return {
students:[]
}
},
methods:{
getStudent(){
axios({
url:"http://localhost:8080/stu/students",
method: 'GET',
}).then(res=>{
console.log(res.data);
this.students=res.data;
})
}
}
}
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round @click="delStu">删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
},
delStu(){
axios({
url:"http://localhost:8080/stu/delete",
method:"POST",
data:this.localStudent
})
}
}
}
</script>
<style>
</style>
弹出对话框
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
<el-button plain @click="dialogVisible = true">
Click to open the Dialog
</el-button>
<el-dialog
v-model="dialogVisible"
title="Tips"
width="500"
:before-close="handleClose"
>
<span>This is a message</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="dialogVisible = false">
Confirm
</el-button>
</div>
</template>
</el-dialog>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg
v-for="stu in students"
:key="stu.id"
:student="stu"
></StudentEgg>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from "axios";
import StudentEgg from "./components/StudentEgg.vue";
export default {
name: "App",
components: {
StudentEgg,
},
data() {
return {
students: [],
dialogVisible:false
};
},
methods: {
getStudent() {
axios({
url: "http://localhost:8080/stu/students",
method: "GET",
}).then((res) => {
console.log(res.data);
this.students = res.data;
});
},
handleClose(done){
this.$confirm('确认关闭?')
.then(()=>{
done();
})
.catch(()=>{});
}
},
};
</script>
<style>
</style>
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round @click="delStu">删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
},
delStu(){
axios({
url:"http://localhost:8080/stu/delete",
method:"POST",
data:this.localStudent
})
}
}
}
</script>
<style>
</style>
将对话框改造成“添加学生信息”
至此,前端代码:
App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
<el-button plain @click="dialogVisible = true">
添加学生信息
</el-button>
<el-dialog
v-model="dialogVisible"
title="添加"
width="500"
:before-close="handleClose"
>
<div>输入学生信息:</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addStudent">添加</el-button>
</div>
</template>
<div>
<span>姓名</span><input type="text" v-model="newStudent.name">
</div>
<div>
<span>学号</span><input type="text" v-model.number="newStudent.stuid">
</div>
<div>
<span>班级</span><input type="text" v-model="newStudent.classroom">
</div>
<div>
<span>成绩</span><input type="text" v-model.number="newStudent.grade">
</div>
</el-dialog>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg
v-for="stu in students"
:key="stu.id"
:student="stu"
></StudentEgg>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from "axios";
import StudentEgg from "./components/StudentEgg.vue";
export default {
name: "App",
components: {
StudentEgg,
},
data() {
return {
students: [],
dialogVisible:false,
newStudent:{
name:"",
stuid:"",
classroom:"",
grade:""
}
};
},
methods: {
getStudent() {
axios({
url: "http://localhost:8080/stu/students",
method: "GET",
}).then((res) => {
console.log(res.data);
this.students = res.data;
});
},
handleClose(done){
this.$confirm('确认关闭?')
.then(()=>{
done();
})
.catch(()=>{});
},
addStudent(){
axios({
url: 'http://localhost:8080/stu/add',
method: 'POST',
data:this.newStudent
})
this.dialogVisible = false
}
},
};
</script>
<style>
</style>
StudentEgg.vue
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round @click="delStu">删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
},
delStu(){
axios({
url:"http://localhost:8080/stu/delete",
method:"POST",
data:this.localStudent
})
}
}
}
</script>
<style>
</style>
其他修改
修改 01
修改 02
修改 03
删除后页面不会立刻刷新变化,手动刷新一次才会变化
现在修改
如果删除的时候,没反应,还没删掉页面就刷新了,可以把这里添加的这一行代码删掉
至此,前端代码:
App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover" style="text-align: center;">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
<el-button type="warning" plain @click="dialogVisible = true">添加学生信息</el-button>
<el-dialog
v-model="dialogVisible"
title="添加"
width="500"
:before-close="handleClose"
>
<div>输入学生信息:</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addStudent">添加</el-button>
</div>
</template>
<div>
<span>姓名</span><input type="text" v-model="newStudent.name">
</div>
<div>
<span>学号</span><input type="text" v-model.number="newStudent.stuid">
</div>
<div>
<span>班级</span><input type="text" v-model="newStudent.classroom">
</div>
<div>
<span>成绩</span><input type="text" v-model.number="newStudent.grade">
</div>
</el-dialog>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg
v-for="stu in students"
:key="stu.id"
:student="stu"
></StudentEgg>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from "axios";
import StudentEgg from "./components/StudentEgg.vue";
export default {
name: "App",
components: {
StudentEgg,
},
data() {
return {
students: [],
dialogVisible:false,
newStudent:{
name:"",
stuid:"",
classroom:"",
grade:""
}
};
},
methods: {
getStudent() {
axios({
url: "http://localhost:8080/stu/students",
method: "GET",
}).then((res) => {
console.log(res.data);
this.students = res.data;
});
},
handleClose(done){
this.$confirm('确认关闭?')
.then(()=>{
done();
})
.catch(()=>{});
},
addStudent(){
axios({
url: 'http://localhost:8080/stu/add',
method: 'POST',
data:this.newStudent
})
this.dialogVisible = false
}
},
};
</script>
<style>
</style>
StudentEgg.vue
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round @click="delStu">删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
},
delStu(){
axios({
url:"http://localhost:8080/stu/delete",
method:"POST",
data:this.localStudent
})
location.reload();
}
}
}
</script>
<style>
</style>
分页实现
添加这些 elementui 的代码:
将分页按钮居中
至此,实现页面分页,每页五条信息
至此,前端代码
App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover" style="text-align: center;">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
<el-button type="warning" plain @click="dialogVisible = true">添加学生信息</el-button>
<el-dialog
v-model="dialogVisible"
title="添加"
width="500"
:before-close="handleClose"
>
<div>输入学生信息:</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addStudent">添加</el-button>
</div>
</template>
<div>
<span>姓名</span><input type="text" v-model="newStudent.name">
</div>
<div>
<span>学号</span><input type="text" v-model.number="newStudent.stuid">
</div>
<div>
<span>班级</span><input type="text" v-model="newStudent.classroom">
</div>
<div>
<span>成绩</span><input type="text" v-model.number="newStudent.grade">
</div>
</el-dialog>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩∈[0,999]</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg
v-for="stu in students_for_page"
:key="stu.id"
:student="stu"
></StudentEgg>
</tbody>
</table>
<div class="text-center">
<el-button-group>
<el-button type="primary" icon="il-icon-arrow-left" @click="last_page">上一页</el-button>
<el-button type="primary" @click="next_page">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
</el-button-group>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import StudentEgg from "./components/StudentEgg.vue";
export default {
name: "App",
components: {
StudentEgg,
},
data() {
return {
page:1,
students: [],
dialogVisible:false,
newStudent:{
name:"",
stuid:"",
classroom:"",
grade:""
}
};
},
methods: {
getStudent() {
axios({
url: "http://localhost:8080/stu/students",
method: "GET",
}).then((res) => {
console.log(res.data);
this.students = res.data;
});
},
handleClose(done){
this.$confirm('确认关闭?')
.then(()=>{
done();
})
.catch(()=>{});
},
addStudent(){
axios({
url: 'http://localhost:8080/stu/add',
method: 'POST',
data:this.newStudent
})
this.dialogVisible = false
},
next_page(){
this.page +=1;
},
last_page(){
this.page -=1;
}
},
computed:{
students_for_page(){
return this.students.slice(this.page*5-5,this.page*5);
}
}
};
</script>
<style>
</style>
StudentEgg.vue
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round @click="delStu">删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
},
delStu(){
axios({
url:"http://localhost:8080/stu/delete",
method:"POST",
data:this.localStudent
})
location.reload();
}
}
}
</script>
<style>
</style>
登录和注册
登录和注册按钮做成这样:
使用这两个按钮:
创建数据库表格并添加一个数据
USE egg;
CREATE TABLE USER(
id INT AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
passwords VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
后端操作
- entity.User
package com.example.eggbox.entity;
import lombok.Data;
@Data
public class User {
private Integer id;
private String username;
private String passwords;
}
- controller.UserController
package com.example.eggbox.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.eggbox.entity.User;
import com.example.eggbox.mapper.UserMapper;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* <p>
* 前端控制器
* </p>
*
* @author author
* @since 2024-05-25
*/
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = {"*","null"})
public class UserController {
@Autowired
private UserMapper userMapper;
private Gson gson=new Gson();
@PostMapping("/login")
public String loginStudent(@RequestBody User user){
QueryWrapper<User>userQueryWrapper=new QueryWrapper<>();
userQueryWrapper.setEntity(user);
User user_selected=userMapper.selectOne(userQueryWrapper);
if (user_selected==null){
return "0";
}
return "1";
}
@PostMapping("/register")
public void register(@RequestBody User user){
userMapper.insert(user);
}
}
后端启动成功:
前端操作
修改变量名:
至此,登录功能完成:
- App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover" style="text-align: center;">
<caption class="text-center">
<h1>学生成绩管理系统</h1>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
<el-button type="warning" @click="dialogVisible = true">添加学生信息</el-button>
<el-dialog v-model="dialogVisible" title="添加" width="500" :before-close="handleClose" >
<div>输入学生信息:</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addStudent">添加</el-button>
</div>
</template>
<div>
<span>姓名</span><input type="text" v-model="newStudent.name">
</div>
<div>
<span>学号</span><input type="text" v-model.number="newStudent.stuid">
</div>
<div>
<span>班级</span><input type="text" v-model="newStudent.classroom">
</div>
<div>
<span>成绩</span><input type="text" v-model.number="newStudent.grade">
</div>
</el-dialog>
<el-button type="primary" circle @click="dialogVisibleLogin = true">登录</el-button>
<el-dialog v-model="dialogVisibleLogin" title="登录" width="500" :before-close="handleClose">
<div>输入用户信息</div>
<div>
<span>账 户</span><input type="text" v-model="user_for_login.username"/>
</div>
<div>
<span>密 码</span><input type="password" v-model="user_for_login.passwords"/>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisibleLogin = false">取消</el-button>
<el-button type="primary" @click="login">登录</el-button>
</div>
</template>
</el-dialog>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩∈[0,999]</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg
v-for="stu in students_for_page"
:key="stu.id"
:student="stu"
></StudentEgg>
</tbody>
</table>
<div class="text-center">
<el-button-group>
<el-button type="primary" icon="il-icon-arrow-left" @click="last_page">上一页</el-button>
<el-button type="primary" @click="next_page">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
</el-button-group>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import StudentEgg from "./components/StudentEgg.vue";
export default {
name: "App",
components: {
StudentEgg,
},
data() {
return {
user_for_login:{
username:"",
passwords:""
},
page:1,
students: [],
dialogVisible:false,
dialogVisibleLogin:false,
newStudent:{
name:"",
stuid:"",
classroom:"",
grade:""
}
};
},
methods: {
getStudent() {
if(sessionStorage.getItem("isLogined")=="true"){
axios({
url: "http://localhost:8080/stu/students",
method: "GET",
}).then(res => {
console.log(res.data);
this.students = res.data;
});
}else{
this.$alert("尚未登录,请先登录");
}
},
handleClose(done){
this.$confirm('确认关闭?')
.then(()=>{
done();
})
.catch(()=>{});
},
addStudent(){
axios({
url: 'http://localhost:8080/stu/add',
method: 'POST',
data:this.newStudent
})
this.dialogVisible = false
},
next_page(){
this.page +=1;
},
last_page(){
this.page -=1;
},
login(){
axios({
url: 'http://localhost:8080/user/login',
data: this.user_for_login,
method:"POST"
}).then(res =>{
console.log(res.data);
if(res.data=="1"){
sessionStorage.setItem("isLogined","true");
alert("登陆成功,点击继续");
}else{
alert("用户名或密码错误");
}
})
this.dialogVisibleLogin=false
}
},
computed:{
students_for_page(){
return this.students.slice(this.page*5-5,this.page*5);
}
}
};
</script>
<style>
</style>
- StudentEgg.vue
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round @click="delStu">删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
},
delStu(){
axios({
url:"http://localhost:8080/stu/delete",
method:"POST",
data:this.localStudent
})
location.reload();
}
}
}
</script>
<style>
</style>
注册功能
复制到这里
至此,前端代码:
App.vue
<template>
<div id="app">
<div class="col-8 offset-2">
<table class="table caption-top table-hover" style="text-align: center;">
<caption class="text-center">
<h1>学生信息管理系统</h1>
<el-button circle type="danger" @click="dialogVisibleRegister = true">注册</el-button>
<el-dialog v-model="dialogVisibleRegister" title="注册" width="500" :before-close="handleClose">
<span>输入注册信息</span>
<div>
<span>新建账户:</span><input type="text" v-model="user_for_register.username">
</div>
<div>
<span>账户密码:</span><input type="password" v-model="user_for_register.passwords">
</div>
<div>
<span>确认密码:</span><input type="password" v-model="user_for_register.confirmPassword">
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisibleRegister = false">取消</el-button>
<el-button type="primary" @click="register">注册</el-button>
</div>
</template>
</el-dialog>
<el-button type="success" @click="getStudent">获取学生信息</el-button>
<el-button type="warning" @click="dialogVisible = true">添加学生信息</el-button>
<el-dialog v-model="dialogVisible" title="添加" width="500" :before-close="handleClose" >
<div>输入学生信息:</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addStudent">添加</el-button>
</div>
</template>
<div>
<span>姓名</span><input type="text" v-model="newStudent.name">
</div>
<div>
<span>学号</span><input type="text" v-model.number="newStudent.stuid">
</div>
<div>
<span>班级</span><input type="text" v-model="newStudent.classroom">
</div>
<div>
<span>成绩</span><input type="text" v-model.number="newStudent.grade">
</div>
</el-dialog>
<el-button type="primary" circle @click="dialogVisibleLogin = true">登录</el-button>
<el-dialog v-model="dialogVisibleLogin" title="登录" width="500" :before-close="handleClose">
<div>输入用户信息</div>
<div>
<span>账 户</span><input type="text" v-model="user_for_login.username"/>
</div>
<div>
<span>密 码</span><input type="password" v-model="user_for_login.passwords"/>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisibleLogin = false">取消</el-button>
<el-button type="primary" @click="login">登录</el-button>
</div>
</template>
</el-dialog>
</caption>
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">学号</th>
<th scope="col">班级</th>
<th scope="col">成绩∈[0,999]</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<StudentEgg
v-for="stu in students_for_page"
:key="stu.id"
:student="stu"
></StudentEgg>
</tbody>
</table>
<div class="text-center">
<el-button-group>
<el-button type="primary" icon="il-icon-arrow-left" @click="last_page">上一页</el-button>
<el-button type="primary" @click="next_page">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
</el-button-group>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import StudentEgg from "./components/StudentEgg.vue";
export default {
name: "App",
components: {
StudentEgg,
},
data() {
return {
user_for_login:{
username:"",
passwords:""
},
user_for_register:{
username:"",
passwords:"",
confirmPassword:""
},
page:1,
students: [],
dialogVisible:false,
dialogVisibleLogin:false,
dialogVisibleRegister:false,
newStudent:{
name:"",
stuid:"",
classroom:"",
grade:""
}
};
},
methods: {
getStudent() {
if(sessionStorage.getItem("isLogined")=="true"){
axios({
url: "http://localhost:8080/stu/students",
method: "GET",
}).then(res => {
console.log(res.data);
this.students = res.data;
});
}else{
this.$alert("尚未登录,请先登录");
}
},
handleClose(done){
this.$confirm('确认关闭?')
.then(()=>{
done();
})
.catch(()=>{});
},
addStudent(){
axios({
url: 'http://localhost:8080/stu/add',
method: 'POST',
data:this.newStudent
})
this.dialogVisible = false
},
next_page(){
this.page +=1;
},
last_page(){
this.page -=1;
},
login(){
axios({
url: 'http://localhost:8080/user/login',
data: this.user_for_login,
method:"POST"
}).then(res =>{
console.log(res.data);
if(res.data=="1"){
sessionStorage.setItem("isLogined","true");
alert("登陆成功,点击继续");
}else{
alert("用户名或密码错误");
}
})
this.dialogVisibleLogin=false
},
register(){
axios({
url:"http://localhost:8080/user/register",
method:"POST",
data:this.user_for_register
})
this.dialogVisibleRegister=false;
this.$alert("注册成功")
}
},
computed:{
students_for_page(){
return this.students.slice(this.page*5-5,this.page*5);
}
}
};
</script>
<style>
</style>
StudentEgg.vue
<template>
<tr>
<td v-show="!is_edit">{{ localStudent.name }}</td>
<td v-show="!is_edit">{{ localStudent.stuid }}</td>
<td v-show="!is_edit">{{ localStudent.classroom }}</td>
<td v-show="!is_edit">{{ localStudent.grade }}</td>
<td v-show="!is_edit">
<el-button type="primary" round @click="modify">修改</el-button>
<el-button type="danger" round @click="delStu">删除</el-button>
</td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.name"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.stuid"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model="localStudent.classroom"/></td>
<td v-show="is_edit"><input class="w-50" type="text" v-model.number="localStudent.grade"/></td>
<td v-show="is_edit">
<el-button type="primary" round @click="save">保存</el-button>
<el-button type="danger" round>删除</el-button>
</td>
</tr>
</template>
<script>
import axios from 'axios'
export default {
props:["student"],
data(){
return {
is_edit:false,
localStudent:{...this.student}
};
},
watch:{
student:{
handler(newStudent){
this.localStudent = {...newStudent};
},
immediate: true
}
},
methods:{
modify(){
this.is_edit=true;
},
save() {
axios({
url: "http://localhost:8080/stu/update",
method: "POST",
data: this.localStudent // 修正为使用 localStudent
})
.then(() => {
this.$emit("update:student", this.localStudent); // 修正事件名为 "update"
this.is_edit = false;
})
.catch(error => {
console.error("更新学生信息时发生错误:", error);
// 可能需要在这里处理错误情况,比如通知用户
});
},
delStu(){
axios({
url:"http://localhost:8080/stu/delete",
method:"POST",
data:this.localStudent
})
location.reload();
}
}
}
</script>
<style>
</style>