bestvike 练习4 --vue2.0+elementui实现教师管理系统

发布于:2024-04-16 ⋅ 阅读:(16) ⋅ 点赞:(0)

首先总结需求:
基于elementui使用vue脚手架写一个教师管理界面:https://demo.bestvike.com/bv-train-cli/#/
教师列表是标题,新增弹窗界面:失去焦点,检验空,编号姓名验重
搜索框空的时候点搜索就是初始界面:可以按地址查询,可以按姓名查询,教师编号,也可以按照日期
所以说数字和字段包含所有里面搜搜,只要含有就展示
高级搜索点击搜索框变成多个,高级搜索编程收起;空值查询的时候为初界面
多选的时候,新增按钮变为红色删除按钮;只有一个选中的时候有修改和删除按钮,成功之后都会弹窗成功
修改跳转新的界面
https://demo.bestvike.com/bv-train-cli/#/
modify?id=001&
name=%E5%88%98%E6%94%BF%E5%A7%94&sex=1&
inDate=2024-04-09&
address=qwe&
subject=2
姓名带有超链接,
https://demo.bestvike.com/bv-train-cli/#/
detail?id=001&
name=%E5%88%98%E6%94%BF%E5%A7%94&
sex=1&
inDate=2024-04-09&
address=qwe&
subject=2
教师详情界面展示基本信息,返回按钮跳转页面
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

工程目录结构

在这里插入图片描述

public/index.html

—将组件写到html里面,重要的就是如图所示蓝色部分
在这里插入图片描述

router/index.js

–在这里配置路由,不同的路由跳转不同的界面,如图根目录的组件是list,另外导入组件有两种方式,第一种就是在页面一开始import,另外一种就是在配置路由的那一行中进行import,如图所示
在这里插入图片描述

store/global.js

–用来存储一些都可以用到的固定数据,在这里是性别和学科的字典
在这里插入图片描述

store/index.js

vuex

–vuex用来存储组件之间用到的数据,state中存储共享数据,teachers就是初始化一个数据;mutations就是实际执行的方法,由action中的函数进行调用,比如说,在组件中this.$store.dispatch(‘updateTeacher’, updatedTeachers),其中黄色部分就是type类型,actions就会根据type进行具体的操作updateTeacher({ commit }, updatedTeachers) {commit(‘UPDATE_TEACHER’, updatedTeachers); } updatedTeachers就是传过来的数据,经由actions的commit操作之后,就会调用mutations中的**‘UPDATE_TEACHER’**函数,然后进行函数的操作
在这里插入图片描述
在这里插入图片描述

views文件夹

中的组件就是我所要展示的不同界面
== 重要的一件事,在组件中的template标签中,只能有一个根标签,所以可以写一个div,在div中可以写很多的标签 ==

list.vue、detail.vue、modify.vue

App.vue --父组件

index.html展示的就是这个组件,在这个组件中缓存主页面list,另外标签中就是展示的router配置好的东西进行展示,这里有点展示了父子组件的意思
在这里插入图片描述

main.js

main.js 文件通常是一个程序或项目的入口文件,特别是在使用 JavaScript 进行前端开发时。这个文件负责导入其他模块或脚本,并通常包含启动应用的逻辑。在 Node.js 环境中,main.js 也可以作为应用的启动脚本,它将调用应用的其他部分。
以下是一些常见的用途:

  1. 入口点:对于很多 JavaScript 项目来说,main.js 是整个应用的启动点。它通常会导入其他的模块或脚本,并开始执行应用的逻辑。

  2. 初始化代码:在这个文件中,你可以执行一些初始化操作,比如设置应用的状态,配置全局变量,或者启动某些后台任务。

  3. 依赖管理main.js 也常用于导入和初始化项目所需的第三方依赖或模块。

  4. 路由和系统配置:在 web 应用中,main.js 可能包含路由配置,决定用户请求哪个页面或功能。同时,它也可能包含系统级别的配置,如数据库连接、API 端点等。

  5. 错误处理和日志:该文件可能包含错误处理和日志记录的设置,确保应用运行时能够记录重要的信息和错误。

  6. 渲染和显示:在前端项目中,main.js 可能会包含将数据渲染到 DOM 的逻辑,或者控制用户界面显示的脚本。
    每个项目都有其特定的结构和需求,所以 main.js 的具体内容和作用可能会有所不同。在 Node.js 环境中,main.js 常常是 package.json 文件中指定的启动脚本的目标文件。在 ECMAScript 模块系统中,它可能是一个模块导出的目的地,或者是一个模块的顶级作用域。

                                          我来用通俗的语言解释一下 `main.js` 文件是干啥用的。
    

想象一下,一个大的商场或者超市,里面有很多不同的部门和商品,比如食品区、服装区、家电区等等。每个部门都有自己的工作人员和货物。那么,有一个地方是所有工作人员和货物都必须经过的,这个地方就是商场的入口。
在这个情况下,main.js 就像是这个商场的入口。它是整个项目或者应用的开始的地方,所有的事情都是从这里开始的。就像顾客进入商场后,才能去到不同的部门一样,当你的应用开始运行时,它会首先执行 main.js 里面的代码,然后才能使用其他的功能和模块。
main.js 里面通常会做一些事情,比如:

  1. 打招呼:应用启动时,可能首先会显示一个欢迎信息。

  2. 准备购物车:在应用开始时,可能需要初始化一些数据结构,比如购物车。

  3. 安排工作人员:加载和配置需要用到的各种功能模块,就像是安排商场的各个部门的工作人员。

  4. 摆放货物:加载和显示商场的商品,也就是展示应用的内容。

  5. 处理顾客的需求:根据用户的行为和请求,做出相应的响应和处理。
    所以,main.js 就像是商场的入口,是整个购物体验的开始,没有它,顾客就无法进入商场,也就无法购物了。

                                           我来举一些例子,帮你更好地理解 `main.js` 文件的用途:
    
  6. 网站的首页:在一个网页项目中,main.js 可能会包含加载首页所需的所有资源和逻辑,比如图片轮播、导航栏的动画效果等。

  7. 应用的启动逻辑:在一个 Node.js 应用中,main.js 可能包含了启动服务器、设置监听端口等初始化操作。

  8. 游戏的主循环:在一个游戏项目中,main.js 可能包含了游戏的主循环,负责更新游戏状态、渲染画面等。

  9. 数据处理main.js 可能包含了处理用户输入、从数据库读取数据、计算结果等逻辑。

  10. 用户界面交互:在前端项目中,main.js 可能会包含各种用户界面的交互逻辑,比如点击按钮弹出提示框、下拉菜单的变化等。

  11. 动画和特效:在一些项目中,main.js 可能会包含实现动画和特效的代码,比如滚动时变化的背景、旋转的图标等。

  12. 网络请求main.js 可能负责发送网络请求,比如从其他服务器获取数据、上传图片等。

  13. 模块导出:在一个模块化的大型项目中,main.js 可能是一个模块的导出目的地,用于将其他文件中的功能或数据导出,方便其他文件或项目使用。

  14. 错误处理和日志记录:在各种应用中,main.js 可能会包含错误处理和日志记录的逻辑,帮助开发者和用户更好地了解应用的运行状况。

  15. 配置和设置:在一些复杂的项目中,main.js 可能会包含各种配置和设置,比如环境变量的设置、第三方服务的接入等。
    总的来说,main.js 是一个项目的核心文件,负责整合和调度项目的各种功能和资源。具体它能干什么,取决于项目的需求和开发者的设计。
    在这里插入图片描述
    其中这里创建了父组件App

list.vue–首页面

整体框架

观察界面先把大的框架写出来,按行来分可以分为教师列表,新增按钮(修改删除按钮),搜索栏(高级搜索栏),表单
之前提到的根标签div,可以设置他的位置是居中的还有它的宽度
在这里插入图片描述

钩子函数

创建的时候献给teachers赋一个初始值—传值还有接受
在这里插入图片描述

新增修改删除按钮

新增按钮:

新增按钮是在列表中没有选中的情况下才会出现,居最右

复选框

给每个教师定义一个属性isSelected,根据复选框的状态,来定义变量(布尔型)用来展示新增修改删除按钮

      // 根据选中的行数来决定是否显示删除按钮修改按钮
      if (val.length > 0) {
        this.showDeleteButton = true
        if (val.length === 1) {
          this.showEditButton = true
        } else {
          this.showEditButton = false
        }
      } else {
        this.showDeleteButton = false
        this.showEditButton = false
      }
    },
展示新增按钮
<el-col v-show="!showDeleteButton" >
           <div style="text-align: right;">
           <el-button type="primary" @click="dialogFormVisible = true" icon="el-icon-plus">新增</el-button>
           </div>
新增教师弹窗

点击新增按钮之后会跳出新增用户表单弹窗dialog,这里使用了新增按钮的点击事件,会使dialogFormVisible 的值为true,即会显示dialog,定义dialog全局居左,就是里面的元素都是靠左。
弹窗里面是一个form表单:model就是表单绑定的数据,:rules就是绑定的表单验证规则,其中rules在data中声明,ref就是一定要有,后续在判断表单验证是否全部通过的时候起到很重要的作用
使用来进行每一行的分割,其中前两行由于有两个元素所以使用和来进行元素之间的间距。
在这里插入图片描述

教师编号和教师姓名
**label**就是指的输入框前面显示的文字 **prop**的值"number"表示这个表单项对应的是teacher对象中的number属性。 输入框中:v-model双向数据绑定,style调整宽度,clearable就是可以清除input数据,不需要加等号 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/21a43716ee4643b490a5d1bea934dbdf.png)
性别和学科

<el-radio-group 中v-model进行双向数据绑定,
<el-radio 中使用v-for遍历字典中的对象(就是{对应关系})
== 疑问==
<el-select 中placeholder显示初始值
<el-option 中使用v-for遍历字典中的对象(就是{对应关系})
在这里插入图片描述

入职日期

<el-date-picker type="date"写不写都无所谓,这里绑定的值是:Wed Apr 17 2024 00:00:00 GMT+0800 (中国标准时间)
后边添加教师的函数中需要进行格式转换,转换为yyyy-mm-dd的字符串日期形式:
// const date=new Date(this.teacher.date)
// this.teacher.date=date.getFullYear() + “-” + (date.getMonth() + 1).toString().padStart(2, ‘0’) + “-” + date.getDate().toString().padStart(2, ‘0’);
在这里插入图片描述

地址

maxlength=“200” show-word-limit 字数限制并展示
在这里插入图片描述

表单验证规则rules

格式如下:验空如第一行所示
{required: true, message: ‘请输入编号’, trigger: ‘blur’},
在这里插入图片描述
验重的时候需要自定义函数
{ validator: this.numberRepeat, message: ‘编号重复’, trigger: ‘blur’ },
在这里插入图片描述
另外失去焦点时blur,改变时change

确定取消按钮

在dialog界面中居中显示,
点击函数,这里的函数名add(‘teacher’),中间的是表明,与ref保持一致,并且需要加引号
在这里插入图片描述
添加教师的函数 add(teacher):---->这里teacher的值就是 'teacher’表名,不是什么对象
①这里的teacher就是函数中的那个参数就是上面的teacher
this.$refs[teacher].validate((valid) => {
if (valid) { //如果合法要执行的操作
}
});
②首先就是对于日期的格式化
const date=new Date(this.teacher.date)
this.teacher.date=date.getFullYear() + “-” + (date.getMonth() + 1).toString().padStart(2, ‘0’) + “-” + date.getDate().toString().padStart(2, ‘0’);
③复制一个teacher并且push到teachers中,将teachers传到vuex中,每执行一次add函数都会更新一次
④清空表单信息,设置展示弹窗的flag为false,展示成功信息
在这里插入图片描述
取消按钮 同理
在这里插入图片描述

修改删除按钮:

在这里插入图片描述
点击修改调用modify方法进行路由跳转
在这里插入图片描述
点击删除调用deleteSome方法进行路由跳转
在这里插入图片描述

搜索与高级搜索

此处设计三个flag,第一个:isSearching—模糊搜索中
第二个:changeAdvancedSearching—搜索栏由模糊搜索转换为高级搜索栏
第三个:isAdvancedSearching—高级搜索中
在这里插入图片描述

模糊查询:

首先前面有输入框还有一个🔍,输入框有回车事件@keyup.native.enter,点击🔍都会触发搜索,
这个搜索是模糊查询
在这里插入图片描述
切换到高级搜索是用了文字按钮,切换两种搜索状态通过设置一个flag,点击高级搜索的时候,令flag为true从而实现切换。

高级搜索:

在这里插入图片描述
对于入职时间是一个时间选择器,其中type:daterange至关重要,v-model绑定的值是一个数组有两个值
点击查询会调用高级查询的方法 注意逻辑
在这里插入图片描述
点击收起,转换为初始的模糊搜索状态
在这里插入图片描述

教师列表

在这里插入图片描述

切换表格数据

因为展示的情况有不同,初始状态下展示原教师列表,搜索状态下展示搜索后的教师列表,所以使用:
== :data="!isSearching && !AdvancedSearching?teachers:filteredTeachers ==
表格包含复选框、教师编号、教师姓名、性别、学科、入职时间、地址
其中:
复选框使用 type=selection 不用做其他的特殊处理;
教师姓名要带有超链接可以跳转详情页,在标签中定义一个引入插槽

<el-button type=“text” @click=“detail(scope.row)” size=“small”>{{scope.row.name}}

点击姓名就可以跳转路由,这里要传参,传点击姓名的当前行数据
在这里插入图片描述

复选框的选择判断

@selection-change=“handleSelectionChange”
当你把鼠标悬停在一个复选框上,并且点击它时,复选框会被选中或者取消选中。
当你选择了一个复选框,或者多个复选框时,这个事件就会发生。
然后,Vue.js会调用handleSelectionChange这个方法,并且把当前选中的行的数据作为一个参数传递给它。
你在handleSelectionChange方法中可以定义当用户选择或者取消选择行时,你想执行的逻辑,比如更新状态、发送请求等。

设置每个teacher的isSelected的值
设置展示修改删除按钮的flag

在这里插入图片描述

关于scope

我们可以将 “scope” 想象为一个内部通道,它允许表格组件(el-table)的每个列(el-table-column)与它的父组件之间进行数据交换。

当你在 el-table-column 组件中使用 slot-scope 属性时,你实际上是在创建一个可以向父组件暴露数据的通道。在这个通道中,“scope” 就是那个可以携带数据的包裹。

具体来说,在这个例子中:

每个 el-table-column 都有一个 slot-scope 属性,它的值被设定为 “scope”。
当父组件渲染表格时,它会为每个列创建一个插槽。这个插槽可以用来定制列的内容。
通过 slot-scope,父组件可以访问到当前列的数据。这就像是一个小型的作用域,它让你可以在插槽内容中访问 row 对象,即当前行的数据。

源码

<template>
 <div class="center-block"  style=" width: 1300px;">
   <el-container>
     <el-header>
         <h3>教师列表</h3>
     </el-header>
     <el-main>
<!--新增修改删除-->
       <el-row>
         <el-col v-show="!showDeleteButton" >
           <div style="text-align: right;">
           <el-button type="primary" @click="dialogFormVisible = true" icon="el-icon-plus">新增</el-button>
           </div>
           <!--点击新增按钮后的弹窗界面-->
           <div style="text-align: left;">
             <el-dialog title="教师新增" :visible.sync="dialogFormVisible" >
               <el-form :model="teacher" :rules="rules" ref="teacher"  >
                 <el-form-item >
                   <el-row  :gutter="50">
                     <el-col :span="12" >
                       <el-form-item label="教师编号:" prop="number">
                         <el-input v-model="teacher.number"  style="width: 180px;" clearable></el-input>
                       </el-form-item>
                     </el-col>
                     <el-col :span="12" >
                       <el-form-item label="教师姓名:" prop="name"  >
                         <el-input v-model="teacher.name" style="width: 180px;" clearable></el-input>
                       </el-form-item>
                     </el-col >
                   </el-row>
                 </el-form-item>

                 <el-form-item>
                   <el-row :gutter="50">
                     <el-col :span="12">
                       <el-form-item label="性别:" prop="sex">
                         <el-radio-group v-model="teacher.sex"   style="width: 200px;" clearable>
                           <el-radio v-for="option in sexOptions" :key="option.value" :label="option.value" :value="option.value">{{option.label}}</el-radio>
                         </el-radio-group>
                       </el-form-item>
                     </el-col>
                     <el-col :span="12">
                       <el-form-item label="学科" prop="subject">
                         <el-select v-model="teacher.subject" placeholder="请选择学科"  style="width: 200px;" clearable>
                           <el-option v-for="option in subjectOptions" :key="option.value" :label="option.label" :value="option.value"></el-option>
                         </el-select>
                       </el-form-item>
                     </el-col>
                   </el-row>
                 </el-form-item>

                 <el-form-item label="入职日期:" prop="date" required>
                   <el-date-picker type="date" placeholder="选择日期" v-model="teacher.date" style="width: 200px;" clearable></el-date-picker>
                 </el-form-item>

                 <el-form-item label="地址:" prop="address">
                   <el-input  type="textarea" v-model="teacher.address"   style="width: 500px;" maxlength="200" show-word-limit clearable></el-input>
                 </el-form-item>

                 <el-form-item >
                   <el-row type="flex" justify="center" align="middle" style="margin-top: 10px;">
                     <el-button type="primary" @click="add('teacher')"  icon="el-icon-check">确 定</el-button>
                     <el-button @click="resetForm('teacher')"  icon="el-icon-circle-close">取 消</el-button>
                   </el-row>
                 </el-form-item>

               </el-form>
             </el-dialog>
           </div>

         </el-col>
         <el-col :span="24" class="right">
             <el-button  v-show="showEditButton" @click="modify" icon="el-icon-edit">修改</el-button>
             <el-button type="danger"  v-show="showDeleteButton"  @click="deleteSome" icon="el-icon-folder-delete">删除</el-button>
         </el-col>
       </el-row>
       <el-divider></el-divider>
<!--搜索与高级搜索-->
       <el-row>
         <!--搜索-->
         <template v-if="!changeAdvancedSearching">
           <el-col :span="15"  style="margin-top: 15px;">
               <el-input placeholder="请输入内容" v-model="fuzzySearchInput"  @keyup.native.enter="handleEnter" el-icon-circle-close clearable>
                 <el-button slot="append" icon="el-icon-search"  @click="handleEnter"></el-button>
               </el-input>
           </el-col>
           <!--      高级搜索-->
           <el-col :span="9" class="right" style="margin-top: 15px;">
             <el-button type="text" @click="changeAdvancedSearching = true" icon="el-icon-arrow-down el-icon--right">
               高级搜索<i class="el-icon-arrow-down el-icon--right"></i>
             </el-button>
           </el-col>
         </template>

         <template v-else>
           <el-row>
             <!-- 教师姓名-->
             <el-col :span="4" style="margin-top: 15px;">
               教师姓名:<el-input placeholder="请输入" v-model="nameSearchInput"  style="width: 120px;" clearable></el-input>
             </el-col>
             <!-- 学科-->
             <el-col :span="5" >
               <div style="margin-top: 15px;">
               学科:<el-select v-model="subjectSearchInput" slot="prepend" placeholder="请选择" style="width: 180px;" clearable>
                   <el-option v-for="option in subjectOptions" :key="option.value" :label="option.label" :value="option.value">{{ option.label}}</el-option>
                 </el-select>
                 </div >
             </el-col>
             <!--入职时间-->
             <el-col :span="9" style="margin-top: 15px;">
                 入职时间:
                 <el-date-picker type="daterange" v-model="dateSearchInput"
                                 format="yyyy-MM-dd "value-format="yyyy-MM-dd " style="width: 300px;"
                                 start-placeholder="开始日期" end-placeholder="结束日期" range-separator="至"  >
                 </el-date-picker>
             </el-col>
<!--查询-->
             <el-col :span="2" style="margin-top: 15px;">
               <el-button type="primary" icon="el-icon-search"  @click="advancedSearching">
                 查询
               </el-button>
             </el-col>
             <!-- 收起-->
             <el-col :span="4" class="right" style="margin-top: 15px;">
               <el-button type="text" @click="putAway">
                 收起<i class="el-icon-arrow-up el-icon--right"></i>
               </el-button>
             </el-col>
           </el-row>

         </template>

       </el-row>
       <br>
<!--表单-->
         <el-table ref="teachers"  :data="!isSearching && !AdvancedSearching?teachers:filteredTeachers"   tooltip-effect="dark"   border style="width: 100%" @selection-change="handleSelectionChange">
           <el-table-column type="selection" width="55"></el-table-column>
           <el-table-column prop="number" label="教师编号" width="90"></el-table-column>
           <el-table-column prop="name" label="教师姓名" width="120">
             <template slot-scope="scope">
               <el-button  type="text" @click="detail(scope.row)" size="small">{{scope.row.name}}</el-button>
             </template>
           </el-table-column>
           <el-table-column prop="sex" label="性别" width="50">
               <template slot-scope="scope">
               {{ sexOptions.find(option => option.value === scope.row.sex).label }}
               </template>
           </el-table-column>
           <el-table-column prop="subject" label="学科" width="60">
             <template slot-scope="scope">
               {{ subjectOptions.find(option => option.value === scope.row.subject).label }}
             </template>
           </el-table-column>
           <el-table-column prop="date" label="入职时间" width="200">
             <template slot-scope="scope">{{ scope.row.date }}</template>
           </el-table-column>
           <el-table-column prop="address" label="地址" show-overflow-tooltip>
           </el-table-column>
         </el-table>
     </el-main>
   </el-container>
 </div>
</template>

<script>
import { subjectOptions } from '@/store/global';
import { sexOptions } from '@/store/global';

export default {

  name: "list",
  data() {
    return {
      isSearching: false,
      changeAdvancedSearching: false,
      AdvancedSearching: false,
      fuzzySearchInput: '',
      nameSearchInput: '',
      subjectSearchInput: '',
      dateSearchInput: [],
      subjectOptions: subjectOptions,
      sexOptions: sexOptions,
      dialogFormVisible: false,
      teachers: [],
      selectedTeachers: [],
      filteredTeachers: [],
      teacher: {
        isSelected: false,
        number: '',
        name: '',
        sex: '1',
        subject: '',
        date: '',
        address: ''
      },
      formLabelWidth: '120px',
      showDeleteButton: false,
      showEditButton: false,

      rules: {
        number: [
          {required: true, message: '请输入编号', trigger: 'blur'},
          { validator: this.numberRepeat, message: '编号重复', trigger: 'blur' },
        ],
        name: [
          {required: true, message: '请输入姓名', trigger: 'blur'},
          { validator: this.nameRepeat, trigger: 'blur' },
        ],
        sex: [
          {required: true, message: '请选择性别', trigger: 'change'}
        ],
        subject: [
          {required: true, message: '请选择学科', trigger: 'change'}
        ],
        date: [
          { required: true, message: '请选择日期', trigger: 'change'}
        ],
        address: [
          {required: true, message: '请输入地址', trigger: 'blur'}
        ]
      }
    }
  },
  created(){
    this.$store.dispatch('initTeachers', this.teachers);
  },
  methods: {
    numberRepeat(rule, value, callback) {
      if (this.teachers.some(teacher => value === teacher.number)) {
        callback(new Error('编号重复'));
      }else{
        callback()
      }
    },
    nameRepeat(rule, value, callback) {
      if (this.teachers.some(teacher => value === teacher.name)) {
        callback(new Error('姓名重复'));
      }else{
        callback()
      }
    },

    //新增教师
    add(teacher) {
      this.$refs[teacher].validate((valid) => {
        if (valid) {
          const date=new Date(this.teacher.date)
          this.teacher.date=date.getFullYear() + "-" + (date.getMonth() + 1).toString().padStart(2, '0') + "-" + date.getDate().toString().padStart(2, '0');
          this.teachers.push({...this.teacher})
          this.$store.dispatch('updateTeacher', this.teachers);
          this.$refs[teacher].resetFields();
          this.dialogFormVisible = false
          this.$message({
            message: '新增成功',
            type: 'success'
          })
          console.log(this.teachers);
        }
      });
    },
    //取消增加
    resetForm(teacher) {
      this.$refs[teacher].resetFields();
      this.dialogFormVisible = false
    },
    //模糊搜寻(回车)
    handleEnter() {
      if (this.fuzzySearchInput) {
        // 创建一个正则表达式,用于匹配包含模糊查询字符串的属性
        const regex = new RegExp(this.fuzzySearchInput.toLowerCase(), 'i');

        // 只针对编号、姓名、时间、地址进行过滤
        this.filteredTeachers = this.teachers.filter(teacher => {
          return ['number', 'name', 'date', 'address'].some(key => {
            return regex.test(String(teacher[key]).toLowerCase());
          });
        });
        // 如果过滤结果为空,则重置为原始教师列表
        if (this.filteredTeachers.length === 0) {
          this.filteredTeachers = this.teachers;
        }
        this.isSearching = true;
      } else {
        this.filteredTeachers = this.teachers;
        this.isSearching = false;
      }
    },
    //点击收起
    putAway() {
      this.isSearching = false
      this.changeAdvancedSearching = false
      this.AdvancedSearching=false
      this.fuzzySearchInput = ''
    },
    //高级查询
      advancedSearching() {
        this.filteredTeachers = this.teachers; // 初始化过滤后的教师数组
        // 根据输入的搜索条件过滤教师
        if (this.nameSearchInput) {
          this.filteredTeachers = this.filteredTeachers.filter(teacher => teacher.name === this.nameSearchInput);
        }
        if (this.subjectSearchInput) {
          this.filteredTeachers = this.filteredTeachers.filter(teacher => teacher.subject === this.subjectSearchInput);
        }

        if (this.dateSearchInput && this.dateSearchInput.length > 1) {
          const startDate = new Date(this.dateSearchInput[0]);
          const endDate = new Date(this.dateSearchInput[1]);
          this.filteredTeachers = this.filteredTeachers.filter(teacher => {
            const teacherDate = new Date(teacher.date);
            return teacherDate >= startDate && teacherDate <= endDate;
          });
        }
        this.AdvancedSearching = true; // 设置高级搜索状
      },
    //复选框状态
    handleSelectionChange(val) {
      this.selectedTeachers = val;
      if (val) {
        val.forEach(teacher => {
          teacher.isSelected = true
        })
      }
      // 根据选中的行数来决定是否显示删除按钮修改按钮
      if (val.length > 0) {
        this.showDeleteButton = true
        if (val.length === 1) {
          this.showEditButton = true
        } else {
          this.showEditButton = false
        }
      } else {
        this.showDeleteButton = false
        this.showEditButton = false
      }

    },
    //删除
    deleteSome(){
      let i=this.teachers.length
      while (i--){
        if (this.teachers[i].isSelected){
          this.teachers.splice(i, 1)
        }
      }
      this.$message({
        message: '删除成功',
        type: 'success'
      })
    },
    //跳转详情页
    detail(teacher) {
      this.$router.push({
        path: '/detail',
        query: {
          number: teacher.number,
          name: teacher.name,
          sex: teacher.sex,
          date: teacher.date,
          address: teacher.address,
          subject: teacher.subject
        }
      });
    },
    //修改
    modify() {
      this.$router.push({
        path: '/modify',
        query: {
          teacher: this.teachers.filter(teacher => teacher.isSelected)[0]
        }
      })
    },
  },

}
</script>

<style>
.el-form-item__content {
  text-align: left;
}
.right{
  text-align: right;
}
.center-block {
  margin-left: auto;
  margin-right: auto;
}
.el-dialog__title {
  text-align: left; /* 将标题文字对齐到左边 */
  margin-left: 10px; /* 在标题和对话框边缘之间添加一些间距 */
}
</style>


detail.vue -详情页

展示界面:

在这里插入图片描述返回:在这里插入图片描述

数据和钩子函数

在这里插入图片描述

源码

<template>
  <div class="center-block"  style=" width: 1200px;">
 <h3>教师详情</h3>
    <el-divider></el-divider>
  <el-form  class="el-form-item__content">
    <el-row>
      <el-col :span="12">
        <el-form-item  label="教师编号:" :label-width="formLabelWidth">
          {{teacher.number}}
        </el-form-item>
      </el-col >
      <el-col :span="12">
        <el-form-item  label="教师姓名:" :label-width="formLabelWidth">
          {{teacher.name}}
        </el-form-item>
      </el-col >
    </el-row>
    <el-row>
      <el-col :span="12">
        <el-form-item label="性别:" :label-width="formLabelWidth">
          {{ sexOptions.find(option => option.value === teacher.sex).label }}
        </el-form-item>
      </el-col >
      <el-col :span="12">
        <el-form-item  label="学科:" :label-width="formLabelWidth">
          {{ subjectOptions.find(option => option.value === teacher.subject).label }}
        </el-form-item>
      </el-col >
    </el-row>
    <el-row>
      <el-col :span="12">
        <el-form-item label="入职日期:" :label-width="formLabelWidth">
          {{teacher.date}}
        </el-form-item>
      </el-col >
    </el-row>
    <el-row>
      <el-form-item label="地址:" :label-width="formLabelWidth">
        {{teacher.address}}
      </el-form-item>
    </el-row>
  </el-form>
    <router-link to="/" ><el-button style="text-align: right;">返回</el-button></router-link>
  </div>
</template>

<script>
import {sexOptions, subjectOptions} from "@/store/global";

export default {
  name: "detail",
  data(){
    return{
      sexOptions: sexOptions,
      subjectOptions: subjectOptions,
      teacher: {
        number: '',
        name: '',
        sex:'',
        subject: '',
        date: '',
        address: ''
      },
      formLabelWidth: '120px',
    }
  },
  created() {
    this.teacher.number=this.$route.query.number
    this.teacher.name=this.$route.query.name
    this.teacher.sex=this.$route.query.sex
    this.teacher.date=this.$route.query.date
    this.teacher.address=this.$route.query.address
    this.teacher.subject=this.$route.query.subject
  },

}
</script>


modify.vue -修改界面

获取vuex中的数据

在这里插入图片描述

源码

<template>
  <div class="center-block"  style=" width: 1200px;">
    <h3>教师修改</h3>
    <el-divider></el-divider>
    <el-form  :model="teacher"  :rules="rules" ref="teacher"   >
      <el-form-item >
        <el-row  :gutter="50">
          <el-col :span="12" >
            <el-form-item label="教师编号:" prop="number">
              {{ teacher.number }}
            </el-form-item>
          </el-col>
          <el-col :span="12" >
            <el-form-item label="教师姓名:" prop="name"  >
              <el-input v-model="teacher.name" style="width: 180px;" clearable></el-input>
            </el-form-item>
          </el-col >
        </el-row>
      </el-form-item>

      <el-form-item>
        <el-row :gutter="50">
          <el-col :span="12">
            <el-form-item label="性别:" prop="sex">
              <el-radio-group v-model="teacher.sex"   style="width: 200px;" clearable>
                <el-radio v-for="option in sexOptions" :key="option.value" :label="option.value" :value="option.value">{{option.label}}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="学科:" prop="subject">
              <el-select v-model="teacher.subject" placeholder="请选择学科"  style="width: 200px;" clearable>
                <el-option v-for="option in subjectOptions" :key="option.value" :label="option.label" :value="option.value"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form-item>

      <el-form-item label="入职日期:" prop="date" required>
        <el-date-picker type="date" placeholder="选择日期" v-model="teacher.date" style="width: 200px;" clearable></el-date-picker>
      </el-form-item>

      <el-form-item label="地址:" prop="address">
        <el-input  type="textarea" v-model="teacher.address"   style="width: 500px;" maxlength="200" show-word-limit clearable></el-input>
      </el-form-item>

      <el-form-item>
        <el-row type="flex" justify="center" align="middle" style="margin-top: 10px;">
          <el-button type="primary" @click="updateTeacher('teacher')"  icon="el-icon-check">确 定</el-button>
          <el-button @click="goBack"  icon="el-icon-circle-close">取 消</el-button>
        </el-row>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import {sexOptions, subjectOptions} from "@/store/global";

export default {
  name: "modify",
  data(){
    return{
      sexOptions: sexOptions,
      subjectOptions: subjectOptions,
      rules: {
        name: [
          {required: true, message: '请输入姓名', trigger: 'blur'},
          { validator: this.nameRepeat, trigger: 'blur' },
        ],
        sex:[
          {required: true, message: '请输入性别', trigger: 'blur'},
        ],
        subject: [
          { required: true, message: '请选择学科', trigger: 'change' }
        ],
        date: [
          {  required: true, message: '请选择日期', trigger: 'change' }
        ],
        address: [
          { required: true, message: '请输入地址', trigger: 'blur' }
        ]
      },
      teacher: {
        isSelected: true,
        number: '',
        name: '',
        sex:'',
        subject: '',
        date: '',
        address: ''
      },
      formLabelWidth: '120px',
    }
  },
  created() {
    this.teacher=this.$route.query.teacher
  },
  methods:{
    nameRepeat(rule, value, callback) {
        if (this.teachers.filter(teacher =>teacher.number!==this.teacher.number).some(teacher => value === teacher.name)) {
          callback(new Error('姓名重复'));
        }else{
          callback()
        }
    },
    updateTeacher(teacher) {
      this.$refs[teacher].validate((valid) => {
        if (valid) {
          const date=new Date(this.teacher.date)
          this.teacher.date=date.getFullYear() + "-" + (date.getMonth() + 1).toString().padStart(2, '0') + "-" + date.getDate().toString().padStart(2, '0');
          const updatedTeachers = this.teachers
          const index = this.teachers.findIndex(teacher => teacher.number === this.teacher.number)
          if (index !== -1) {
            updatedTeachers.splice(index, 1, this.teacher)
          }
          this.$store.dispatch('updateTeacher', updatedTeachers)
          this.$message({
            message: '修改成功',
            type: 'success'
          })
          this.$router.push('/')
        }
      });

    },
    goBack(){
      this.$router.push('/')
    }

  },
  computed: {
    teachers() {
      return this.$store.state.teachers;
    }
  },
}
</script>