Bootstrap

springboot2+mybatis-plus+vue3创建入门小项目[学生管理系统]02[实战篇]

01学习篇

创建一个 vue 项目

创建这个新的文件夹
image.png
创建前端项目 eggbox
image.png

数据库 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

image.png
设置表格为
image.png

创建后端项目

创建项目

image.png

设置项目

image.pngimage.pngimage.pngimage.png

创建模块

image.png

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);
    }
}

启动项目

image.png

前端增删改查

准备

vscode 打开之前创建的前端项目
image.png
新建一个终端
image.png
启动项目
image.png
安装 axios
image.png
引入 element-plus
npm install element-plus安装 elementplus
image.png
image.png

// 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]
image.png
将这些代码复制到 main.js

import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'

image.png
App.vue 删成这样
image.png
启动项目
image.png

编写代码

复制这些代码
image.png
复制到这里
image.png
image.png
打开看一下
image.png
image.png
image.png

至此

  • 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 网站复制按钮组件
image.pngimage.png


至此

  • 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>

image.png

至此

  • 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>

image.png



至此

  • 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>

image.png
image.png

设置整个页面内容居中以及表格其他设置

image.png
image.png
image.png
image.png

至此

  • 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>

image.png
image.png

修改功能

点击“修改”按钮,表格信息会变成输入框,用户直接在输入框进行修改

先看效果:
image.png
image.png
image.png
image.png

至此,前端代码

  • 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>

删除功能

演示:
image.png
点击删除后:
image.png
再刷新网页:
image.png

至此,前端代码:

  • 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>

image.png

将对话框改造成“添加学生信息”

image.png
image.pngimage.png

至此,前端代码:

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

image.png
image.png

修改 02

image.png
image.png

修改 03

删除后页面不会立刻刷新变化,手动刷新一次才会变化
现在修改
image.png

如果删除的时候,没反应,还没删掉页面就刷新了,可以把这里添加的这一行代码删掉

至此,前端代码:

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 的代码:
image.png
image.png
将分页按钮居中
image.pngimage.png


image.pngimage.png
image.png
image.png
至此,实现页面分页,每页五条信息

至此,前端代码

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>

登录和注册

登录和注册按钮做成这样:
image.png
使用这两个按钮:
image.png


创建数据库表格并添加一个数据

image.png

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;

后端操作

image.png

  • entity.User
package com.example.eggbox.entity;
import lombok.Data;

@Data
public class User {
    private Integer id;
    private String username;
    private String passwords;
}

image.pngimage.png

  • 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);
    }
}

后端启动成功:
image.png

前端操作

image.png
image.png


修改变量名:
image.png
image.png

至此,登录功能完成:

  • 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>账&nbsp;&nbsp;&nbsp;&nbsp;户</span><input type="text" v-model="user_for_login.username"/>
            </div>
            <div>
              <span>密&nbsp;&nbsp;&nbsp;&nbsp;码</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>

注册功能


复制到这里
image.png



image.png
image.png
image.png

至此,前端代码:

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>账&nbsp;&nbsp;&nbsp;&nbsp;户</span><input type="text" v-model="user_for_login.username"/>
            </div>
            <div>
              <span>密&nbsp;&nbsp;&nbsp;&nbsp;码</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>
;