广告
返回顶部
首页 > 资讯 > 数据库 >基于Springboot+vue+elementUI+MySQL的学生信息管理系统(一)前端部分
  • 371
分享到

基于Springboot+vue+elementUI+MySQL的学生信息管理系统(一)前端部分

前端vue.js 2023-10-04 12:10:51 371人浏览 薄情痞子
摘要

源码在本人博客资源当中,本文为项目代码的详细介绍解释,供于大家学习使用 Vue项目的入口文件:mian.js //vue项目入口文件//导入vueimport Vue from 'vue'//导入根组

源码在本人博客资源当中,本文为项目代码的详细介绍解释,供于大家学习使用

Vue项目的入口文件:mian.js

//vue项目入口文件//导入vueimport Vue from 'vue'//导入根组件appimport App from './App'//导入路由文件import router from './router'//导入ElementUIimport ElementUI from 'element-ui'import 'element-ui/lib/theme-chalk/index.CSS'//导入axiOSimport axios from "axios";import VueAxios from "vue-axios";import mavonEditor from 'mavon-editor'import 'mavon-editor/dist/css/index.css'// useVue.use(mavonEditor)//在vue当中挂载elementUI和axiosVue.use(ElementUI)Vue.use(VueAxios, axios)//productionTip设置为 false ,可以阻止 vue 在启动时生成生产提示Vue.config.productionTip = false// axios请求拦截器axios.interceptors.request.use(function (config) {  // 在发送请求之前做些什么,例如加入token  if (sessionStorage.getItem("auth") !== null) {    config.headers.auth = sessionStorage.getItem("auth");  }  return config;}, function (error) {  // 对请求错误做些什么  return Promise.reject(error);});// axios响应拦截器axios.interceptors.response.use(function (response) {  // 在接收响应做些什么,例如跳转到登录页  if (response.data.data === "没有登录") {    response.data.success = true;    router.push("/login");  }  return response;}, function (error) {  // 对响应错误做点什么  return Promise.reject(error);});//创建vue对象new Vue({  el: '#app',  router,  components: { App },  template: ''})

这里唯一的难点就是axios请求拦截器和响应拦截器,就是判断用户有没有登录,没有登录就让他去登录

路由文件index.js

//vue项目的路由文件//导入vueimport Vue from 'vue'//导入路由import Router from 'vue-router'//导入路由对应的组件import Home from '@/pages/Home'import Student from "../pages/Student";import Teacher from "../pages/Teacher";import Team from "../pages/Team";import Course from "../pages/Course"import Login from "../pages/Login";import Test from "../pages/Test";import Chengji from "../pages/Chengji.vue"//在vue中挂载路由Vue.use(Router)export default new Router({  routes: [    {      path: '/',      name: 'Home',      component: Home,      redirect: '/student',      children: [        {          path:'/student',          name: 'Student',          component: Student        },        {          path: '/teacher',          name: 'Teacher',          component: Teacher        },        {          path: '/team',          name: 'Team',          component: Team        },        {          path: '/course',          name: 'Course',          component: Course        },        {path: '/test',name: 'Test',component: Test}      ]    }, {      path: '/login',      name: 'Login',      component: Login,    }  ]})

这里有个子路由的渲染

登录页面:
在这里插入图片描述
Login.vue:

<template>  <div id="login">    <div class="backgroundImg"></div>    <div class="container">      <div class="body">        <div class="title">          学生信息管理系统        </div>        <el-fORM :model="formData" status-icon :rules="rules" ref="ruleForm" label-width="50px" class="form">         <el-form-item label="账号" prop="username" class="form-item">            <el-input v-model="formData.username" placeholder="输入账号"></el-input>          </el-form-item>                    <el-form-item label="密码" prop="passWord" class="form-item">            <el-input type="password" placeholder="输入密码" v-model="formData.password" autocomplete="off"></el-input>          </el-form-item>          <el-form-item class="login-bar">            <el-button type="success" @click="submitForm('ruleForm')">登录</el-button>            <el-button type="danger" @click="resetForm('ruleForm')">重置</el-button>          </el-form-item>        </el-form>      </div>    </div>  </div></template><script>  export default {    name: "Login",    data() {      var validateUsername = (rule, value, callback) => {        if (value === '') {          callback(new Error('请输入账号'));        } else {          callback();        }      }            var validatePassword = (rule, value, callback) => {        if (value === '') {          callback(new Error('请输入密码'));        } else {          callback();        }      };      return {        formData: {          username: '',          password: '',        },        rules: {          username: [            {validator: validateUsername, trigger: 'blur'}          ],          password: [            {validator: validatePassword, trigger: 'blur'}          ],        }              };    },    methods: {      submitForm(formName) {        this.$refs[formName].validate((valid) => {          if (valid) {            this.axios({              method: 'post',              url: '/api/login',              data: {                username: this.formData.username,                password: this.formData.password,              },            }).then((data) => {              let ret = data.data;              if (ret.success) {                this.$message({                  type: 'success',                  message: '登录成功',                });                sessionStorage.setItem("auth", ret.data);                this.$router.push("/")              } else {                this.$message({                  message: ret.data,                  type: 'error',                });              }            })          } else {            return false;          }        });      },            resetForm(formName) {        this.$refs[formName].resetFields();      }    }  }  </script>

主页效果图:
在这里插入图片描述

Home.vue

<template>    <div id="home">      <LeftNav id="leftNav"></LeftNav>      <TopNav id="topNav"></TopNav>      <div class="container">        <transition name="el-fade-in-linear">          <router-view v-show="isRouterAlive" v-if="isRouterAlive">  </router-view>        </transition>      </div>    </div> </template><script>import LeftNav from "../components/LeftNav";    import TopNav from "../components/TopNav";    export default {      name: "Home",      components: {TopNav, LeftNav},      // 提供方法到子组件中      provide() {        return {          reload: this.reload,        }      },      data() {        return {          isRouterAlive: true        }      },      methods: {        // 刷新组件        reload() {          this.isRouterAlive = false;          this.$nextTick(function () {            // 当数据被修改后使用这个方法会回调获取更新后的dom再渲染出来            this.isRouterAlive = true;          });        }      },    }</script>

侧边栏:Left.vue

<template>    <div id="leftNav">      <div class="container">        <button  v-for="item in navData"                     :to="{name: item.toUrl}"                     :class="curNav===item.value?'active':''"                     @click="navClick(item.value, item.toUrl)">          {{item.value}}        </button>              </div>    </div></template><script>    export default {      name: "LeftNav",      inject: ['reload'],      methods: {        // 点击导航栏后,先转化点击状态        navClick: function (curNav, toUrl) {          this.reload();          this.curNav = curNav;          this.$router.push(toUrl);        },        setCurNav: function (newNav) {          this.curNav = newNav;        }      },      data() {        let navMap = {          '/student': "学生管理",          '/team': "班级管理",          '/teacher': "教师管理",          '/course': "课程管理",                  }        return {          navData: [            {              value: '学生管理',              toUrl: '/student',            },            {              value: '班级管理',              toUrl: '/team'            },            {              value: '教师管理',              toUrl: '/teacher'            },            {              value: '课程管理',              toUrl: '/course'            },          ],          curNav: navMap[this.$route.path],        }      },          }</script>

Student.vue

<template>  <div id="student">    <div class="titleBar"><span>学生管理</span></div>    <div class="container">      <div class="body">        <div class="operationBar">          <el-button type="primary" @click="dialogVisible=true">添加学生</el-button>        <el-dialog          top="10vh"          title="学生信息"          :visible.sync="dialogVisible"          :destroy-on-close="true"          @opened="dialoGopen"          @close="dialoGClose"          width="40%">                    <StudentDialog            ref="dialog"            :teams="this.teams"            :teamId="this.currentTeamId"            :initTeamLabel="this.initTeamLabel"            :isCreate="this.isAddButton"            :oldStudentData="{ ...this.oldStudentData }"          >          </StudentDialog>        </el-dialog>          <div class="selectBar">            <el-select              @change="changeLabel"              @clear="()=>{                let path = this.$router.history.current.path;                this.$router.push(path);              }"              v-model="initTeamLabel" clearable placeholder="选择班级">              <el-option                v-for="item in teams"                :key="item.id"                :label="getLabel(item)"                :value="item.id">              </el-option>            </el-select>          </div>                    <div class="findBar">            <input v-model="findKey" type="text" placeholder="根据姓名查询" @keyup.enter="findLikeName"></input>            <el-button type="primary" @click="findLikeName"><i class="el-icon-search"></i></el-button>            <el-button type="primary" @click="()=>{this.findKey=null;findLikeName();}"><i              class="el-icon-refresh-right"></i>重置            </el-button>          </div>        </div>        <!--表格-->        <el-table          v-loading.lock="loading"          :data="studentsData.content"          border          style="width: 96%; margin-left: 1vw; margin-top: 5vh;">                    <el-table-column            label=" #"            width="50">            <template slot-scope="scope">              <span style="margin-left: 10px">{{ scope.$index + 1 }}</span>            </template>          </el-table-column>          <el-table-column            label="学号"            width="100">            <!--通过 Scoped slot 可以获取到 row, column, $index 和 store(table 内部的状态管理)的数据-->            <template slot-scope="scope">              <i class="el-icon-info"></i>              <span style="margin-left: 10px">{{ scope.row.studentNumber }}</span>            </template>          </el-table-column>          <el-table-column            label="班级"            width="200">            <template slot-scope="scope">              <span style="margin-left: 10px">{{ scope.row.teamFullName }}</span>            </template>          </el-table-column>          <el-table-column            label="姓名"            width="100">            <template slot-scope="scope">              <div slot="reference" class="name-wrapper">                <el-tag size="medium" type="info">{{ scope.row.name }}</el-tag>              </div>            </template>          </el-table-column>          <el-table-column            label="性别"            show-overflow-tooltip            width="50">            <template slot-scope="scope">              <span style="margin-left: 10px">{{getGender(scope.row.gender)}}</span>            </template>          </el-table-column>          <el-table-column            label="民族"            width="90">            <template slot-scope="scope">              <span style="margin-left: 10px">{{scope.row.national}}</span>            </template>          </el-table-column>          <el-table-column            label="出生日期"            width="120">            <template slot-scope="scope">              <span style="margin-left: 10px">{{ getDate(scope.row.birthDate) }}</span>            </template>          </el-table-column>          <el-table-column            label="籍贯"            show-overflow-tooltip            width="200">            <template slot-scope="scope">              <span style="margin-left: 10px">{{ scope.row.nativePlace }}</span>            </template>          </el-table-column>          <el-table-column            label="电话号码"            width="130">            <template slot-scope="scope">              <el-tag                type="info"                effect="plain">                {{ scope.row.phoneNumber }}              </el-tag>            </template>          </el-table-column>          <el-table-column label="操作">            <template slot-scope="scope">              <el-button                size="mini"                @click="handleEdit(scope.row)">编辑              </el-button>              <el-button                size="mini"                type="danger"                @click="handleDelete(scope.row.id)">删除              </el-button>            </template>          </el-table-column>        </el-table>        <div class="pageBlock">          <el-pagination            @current-change="handleCurrentChange"            @size-change="handleSizeChange"            :current-page="currentPageNumber"            :page-sizes="[8,16,24,40]"            :page-size="currentPageSize"            layout="total,sizes, prev, pager, next"            :total="this.studentsData.totalCount">          </el-pagination>        </div>      </div>      <Footing class="footing"></Footing>    </div>  </div></template><script>  import Footing from "../components/Footing";  import StudentPopover from "../components/StudentDialog";  import StudentDialog from "../components/StudentDialog";  import { Loading } from "element-ui";  export default {    name: "Student",    components: {StudentDialog, Footing},    inject: ['reload'],    provide() {      return {        reload: this.reload,      }    },    methods: {      // 对话框关闭时的回调函数      dialogClose: function() {        // 默认为添加        this.isAddButton = true;      },      // 对话框打开时,判断是添加还是更新      dialogOpen: function() {        if (this.isAddButton) {          return;        }        // 通过ref找到子组件对其直接控制        let dialog = this.$refs.dialog;        dialog.studentData = dialog.oldStudentData;        dialog.initTeamLabel = dialog.oldStudentData.teamFullName;      },      handleEdit: function(row) {        this.dialogVisible = true;        this.isAddButton = false;        this.oldStudentData = row;      },      // 改变班级option      changeLabel: function (value) {        this.setTeamId(value);        this.getStudentPageData(0, this.currentPageSize);      },      // 设置url的query参数      setTeamId: function (newTeamId) {        let path = this.$router.history.current.path;        // 这里刷新了一次页面        this.$router.push({path, query: {teamId: newTeamId}});        this.currentTeamId = newTeamId;      },      // 设置option的Label      getLabel: function (team) {        let year = this.getYear(team.schoolYear);        return `${year}${team.professional}专业${team.classNumber}`      },      getYear: function (timestamp) {        let date = new Date(timestamp);        return date.getFullYear();      },      // 处理删除按钮      handleDelete: function (id) {        this.axios({          method: 'delete',          url: '/api/students/' + id,        }).then((data) => {          let ret = data.data;          if (ret.success) {            this.$message({              type: 'success',              message: '删除成功',            });            // 当前删除的是否是本页的最后一条数据            if (this.studentsData.content.length === 1 && this.currentPageNumber !== 1) {              this.currentPageNumber--;              this.getStudentPageData(this.currentPageNumber - 1, this.currentPageSize);            } else {              this.getStudentPageData(this.currentPageNumber - 1, this.currentPageSize);            }          } else {            this.$message({              message: '删除失败',              type: 'error',            });          }        })      },      // 处理分页改变      handleCurrentChange: function (val) {        this.currentPageNumber = val;        this.getStudentPageData(this.currentPageNumber - 1, this.currentPageSize);      },      handleSizeChange: function(val) {        // 设置新的页面大小后        this.currentPageSize = val;        // 回到第一页        this.handleCurrentChange(1);      },      // 根据名称查询      findLikeName: function () {        this.handleCurrentChange(1);      },      // 封装axios请求      getStudentPageData: function (number, size) {        this.axios({          method: 'get',          url: '/api/students',          params: {            pageNumber: number,            pageSize: size,            name: this.findKey,            teamId: this.currentTeamId,          }        }).then((data) => {          let ret = data.data;          if (ret.success) {            this.studentsData = ret.data;          } else {            this.$message({              message: '请求数据失败',              type: 'error',            });          }        });      },      // 查询所有班级信息      getTeamAllData: function () {        this.axios({          method: 'get',          url: "/api/teams/all",        }).then((data) => {          let ret = data.data;          if (ret.success) {            this.teams = ret.data;            // 如果初始化时url上有teamId            if (this.currentTeamId != null) {              let i;              let len = ret.data.length;              for (i = 0; i < len; i++) {                if (ret.data[i].id == this.currentTeamId) {                  this.initTeamLabel = this.getLabel(ret.data[i]);                  break;                }              }              if (i == len) {                this.$message({                  message: '不存在指定的班级',                  type: 'error',                });              }            }          } else {            this.$message({              message: '请求数据失败',              type: 'error',            });          }        })      },      getGender: function (gender) {        if (gender === null) {          return '';        }        if (gender) {          return '男';        } else {          return '女';        }      },      getDate: function (timestamp) {        let dateTime = new Date(timestamp);        let year = dateTime.getFullYear();        let month = (dateTime.getMonth() + 1).toString().padStart(2, '0');        let day = dateTime.getDate().toString().padStart(2, '0');        return `${year}-${month}-${day}`      }    },    data() {      // 刚进入页面时从url上获取teamId的初始值      let teamId = this.$route.query.teamId === undefined ? null : this.$route.query.teamId;      return {        // 姓名查询关键词        findKey: null,        // 学生分页数据        studentsData: {},        // 当前页码        currentPageNumber: 1,        // 当前页面数据数量        currentPageSize: 8,        // 所有班级信息用于select        teams: null,        // 当前班级id,用于url上刷新        currentTeamId: teamId,        // 如果url上有班级id,select上显示的是该班级的label        initTeamLabel: null,        // 对话框是否显示        dialogVisible: false,        // 是否是添加按钮        isAddButton: true,        // 旧学生数据 编辑使用        oldStudentData: null,        // 是否显示加载        loading: false,      }    },    created() {      this.loading = true;      this.getStudentPageData(0, this.currentPageSize);      this.getTeamAllData();      this.loading = false;    }  }</script>

studentDialog.vue

<template>  <div id="studentDialog">    <div class="container">      <div class="properties">        <div class="property">          <span class="propertyTitle">学号:</span>          <el-input class="propertyInput" v-model="studentData.studentNumber" placeholder="请输入学号"></el-input>        </div>        <div class="property">          <span class="propertyTitle">班级:</span>          <el-select class="propertyInput"                     @change="labelChange"                     v-model="this.initTeamLabel" clearable placeholder="选择班级">            <el-option              v-for="item in teams"              :key="item.id"              :label="getLabel(item)"              :value="item.id">            </el-option>          </el-select>        </div>        <div class="property">          <span class="propertyTitle">姓名:</span>          <el-input class="propertyInput" v-model="studentData.name" placeholder="请输入姓名"></el-input>        </div>        <div class="property">          <span class="propertyTitle">性别:</span>          <div class="propertyInput">            <el-radio-group v-model="studentData.gender">              <el-radio :label="true"></el-radio>              <el-radio :label="false"></el-radio>            </el-radio-group>          </div>        </div>        <div class="property">          <span class="propertyTitle">民族:</span>          <el-select class="propertyInput" v-model="studentData.national" clearable placeholder="选择民族">            <el-option              v-for="item in nationals"              :key="item"              :value="item">            </el-option>          </el-select>        </div>        <div class="property">          <span class="propertyTitle">出生日期:</span>          <el-date-picker            class="propertyInput"            value-format="timestamp"            v-model="studentData.birthDate"            type="date"            placeholder="选择出生日期">          </el-date-picker>        </div>        <div class="property">          <span class="propertyTitle">籍贯:</span>          <el-input class="propertyInput" v-model="studentData.nativePlace" placeholder="请输入籍贯"></el-input>        </div>        <div class="property">          <span class="propertyTitle">电话号码:</span>          <el-input class="propertyInput"                    maxlength="11"                    show-word-limit                    suffix-icon="el-icon-phone"                    v-model="studentData.phoneNumber"                    placeholder="请输入电话号码"></el-input>        </div>        <div slot="footer" class="dialog-footer">          <el-button @click="closeClick">取 消</el-button>          <el-button type="primary" @click="solveClick">确 定</el-button>        </div>      </div>    </div>  </div></template><script>  export default {    name: "StudentDialog",    props: ['teams', 'isCreate', 'oldStudentData', 'teamId', 'initTeamLabel'],    inject: ['reload'],    methods: {      updateStudent: function() {        this.axios({          method: 'put',          url: '/api/students/' + this.studentData.id,          data: this.studentData,        }).then((data) => {          let ret = data.data;          if (ret.success) {            this.$message({              type: 'success',              message: '更新成功',            });            // 刷新页面            this.reload();          } else {            this.$message({              message: '更新失败' + ret.data,              type: 'error',            });          }        })      },      createStudent: function() {        this.axios({          method: 'post',          url: '/api/students',          data: this.studentData,        }).then((data) => {          let ret = data.data;          if (ret.success) {            this.$message({              type: 'success',              message: '添加成功',            });            // 刷新页面            this.reload();          } else {            this.$message({              message: '添加失败' + ret.data,              type: 'error',            });          }        })      },      // 班级下拉框改变时      labelChange: function(value) {        this.initTeamLabel = value;        this.studentData.teamId = value;      },      // 确定按钮      solveClick: function() {        if (this.isCreate) {          this.createStudent();        } else {          this.updateStudent();        }      },      // 取消处理      closeClick: function() {        // 关闭对话框        this.$parent.$parent.dialogVisible = false;      },      // 设置option的Label      getLabel: function (team) {        let year = this.getYear(team.schoolYear);        return `${year}${team.professional}专业${team.classNumber}`      },      getYear: function (timestamp) {        let date = new Date(timestamp);        return date.getFullYear();      },      setStudentData: function (data) {        this.studentData = data;      }    },    data() {      return {        studentData: {          teamId: this.teamId,        },        nationals: [          "汉族", "壮族", "满族", "回族", "苗族", "维吾尔族", "土家族", "彝族", "蒙古族", "藏族", "布依族", "侗族", "瑶族", "朝鲜族", "白族", "哈尼族",          "哈萨克族", "黎族", "傣族", "畲族", "傈僳族", "仡佬族", "东乡族", "高山族", "拉祜族", "水族", "佤族", "纳西族", "羌族", "土族", "仫佬族", "锡伯族",          "柯尔克孜族", "达斡尔族", "景颇族", "毛南族", "撒拉族", "布朗族", "塔吉克族", "阿昌族", "普米族", "鄂温克族", "怒族", "京族", "基诺族", "德昂族", "保安族",          "俄罗斯族", "裕固族", "乌孜别克族", "门巴族", "鄂伦春族", "独龙族", "塔塔尔族", "赫哲族", "珞巴族"        ],      }    },  }</script><style scoped>  .container {    display: flex;    justify-content: center;  }  .properties {    width: 100%;    display: flex;    flex-direction: column;  }  .property {    width: 80%;    display: flex;    justify-content: space-between;    padding-bottom: 1vh;  }  .propertyTitle {    font-weight: 600;    width: 40%;    display: flex;    justify-content: flex-end;    align-items: center;    padding-right: 1vw;  }  .propertyTitle:before {    content: "*";    color: rgba(241,8,8,0.88);    padding-right: 2px;  }  .propertyInput {    height: 40px;    width: 60%;    display: flex;    align-items: center;  }  .dialog-footer {    display: flex;    justify-content: flex-end;    padding-right: 20%;    padding-top: 1vh;  }</style>

来源地址:https://blog.csdn.net/ziyue13/article/details/130087077

您可能感兴趣的文档:

--结束END--

本文标题: 基于Springboot+vue+elementUI+MySQL的学生信息管理系统(一)前端部分

本文链接: https://www.lsjlt.com/news/423377.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作