VUE3.0+Antdv+Asp.net WebApi开发学生信息管理系统(三)

在B/S系统开发中,前后端分离开发设计已成为一种标准,而VUE作为前端三大主流框架之一,越来越受到大家的青睐,Antdv是Antd在Vue中的实现。本系列文章主要通过Antdv和Asp.net WebApi开发学生信息管理系统,简述前后端分离开发的主要相关内容,仅供学习分享使用,如有不足之处,还请指正。

在本示例项目中,主要包含两大部分:1.前端web项目【vsims.web】2.后端webapi项目【vsims.webapi】,经过前两篇文章的讲解,已经对前端项目的架构和组成部分,以及后端webapi项目的开发有了大致了解。今天继续开发学生管理模块,主要讲解列表,表单开发的相关内容。

涉及知识点

在本示例中,涉及知识点,主要是前端开发相关:

  • 开发工具:HbuilderX
  • 项目框架:VUE3.0+Antdv
  • Antdv控件应用:
    • 列表(a-table):主要用于大量结构化数据的呈现。
    • 表单(a-form):主要用于收集信息,然后提交到后台进行处理,以及数据进行校验等操作。
    • 分页组件(a-pagination):采用分页形式分隔长列表,每次只显示一页列表。
    • 弹出对话窗(a-modal):需要用户处理事务,又不希望跳转页面以致打断工作流程时,可以使用 
      Modal
       在当前页面正中打开一个浮层,承载相应的操作。
    • 其他控件:文本框(a-input),按钮(a-button),单选按钮(a-radio),下拉框(a-select)等控件。关于具体每一个控件的使用,可参考官网说明示例。

功能划分

在本示例中,学生管理模块功能主要分为4个部分:

  • 查询功能:根据输入的查询条件进行查询,此功能是一个form表单。
  • 数据展示:将查询出的结果进行展示,此功能是一个table列表。
  • 分页功能:数据数据较多,需要分页展示,每次展示一页数据。
  • 新增,编辑功能:可以添加学生信息,也可以编辑信息,此功能是一个弹出对话框,嵌套一个form表单。

查询功能

在学生管理模块中,查询功能主要通过学号,姓名两个条件进行查询,代码如下所示:

 1   <  a-form  :model  ="formState"  name  ="horizontal_query"  layout  ="inline"  autocomplete  ="off"  @finish  ="onFinish"  @finishFailed  ="onFinishFailed"  > 
 2       <  a-form-item  label  ="学号"  name  ="no"  > 
 3           <  a-input  v-model:value  ="formState.no"  ></  a-input  > 
 4       </  a-form-item  > 
 5       <  a-form-item  label  ="姓名"  name  ="name"  > 
 6           <  a-input  v-model:value  ="formState.name"  ></  a-input  > 
 7       </  a-form-item  > 
 8       <  a-form-item  > 
 9           <  a-button  type  ="primary"  html-type  ="submit"  > 查询 </  a-button  > 
 10       </  a-form-item  > 
 11       <  a-form-item  > 
 12           <  a-button  type  ="primary"  @click  ="addStudent"  > 新增 </  a-button  > 
 13       </  a-form-item  > 
 14   </  a-form  > 

注意:form表单的提交事件为submit,finish为提交成功后的响应事件,在此事件中可以进行接口调用,如下所示:

 1  const onFinish = (values: any) => {  2       var  no = values.no;  3       var  name = values.name;  4   getStudents(no, name);  5      console.log('Success:' , values);  6   };  7  
 8  const onFinishFailed = (errorInfo: any) => {  9      console.log('Failed:' , errorInfo);  10   };  11  
 12  const getStudents = (no, name) => {  13      dataSource.length = 0 ;  14      getD('/api/Student/GetStudents' , {  15          "pageSize" : pagination.pageSize,  16          "pageNum" : pagination.current,  17          "no" : no,  18          "name" : name  19      }).then(res => {  20   console.log(res);  21           if  (res.status == 200 ) {  22              pagination.total = res.data.count;  //  总记录数 
 23   console.log(pagination.total);  24               for  (let i = 0; i < res.data.items.length; i++ ) {  25   dataSource.push({  26   id: res.data.items[i].id,  27   key: res.data.items[i].id.toString(),  28   no: res.data.items[i].no,  29   name: res.data.items[i].name,  30   age: res.data.items[i].age,  31                      sex: res.data.items[i].sex ? "男" : "女" ,  32   sexValue: res.data.items[i].sex,  33   classesId: res.data.items[i].classesId,  34   classesName: res.data.items[i].classesName,  35   });  36   }  37              state.dataSource = [...dataSource];  38   }  39   });  40  };

其中getStudents方法,多个地方会进行调用,所以进行了封装,主要用于学生列表查询接口访问。

数据展示

数据展示主要使用a-table控件,其中columns定义需要显示的列,data-source绑定数据源,如下所示:

 1   <  a-table  :columns  ="columns"  :data-source  ="dataSource"  bordered :pagination  ="false"  :row-key  ="record => record.id"  > 
 2       <  template  #bodyCell  ="{ column, text, record }"  > 
 3           <  template  v-if  ="[ 'no','name', 'sge', 'dex','classesName'].includes(column.dataIndex)"  > 
 4               <  div  > {{ text }} </  div  > 
 5           </  template  > 
 6           <  template  v-else-if  ="column.dataIndex === 'operation'"  > 
 7               <  div  class  ="editable-row-operations"  > 
 8                   <  a  @click  ="edit(record.key)"  > Edit </  a  > 
 9               </  div  > 
 10           </  template  > 
 11       </  template  > 
 12   </  a-table  > 

注意:默认情况下,当数据源发生更新时,a-table控件不会信息页面刷新,需要绑定row-key属性才可以。

分页功能

分页功能主要才用分页控件a-pagination,其中current表示当前页,total表示总页码,change表示绑定分页事件,如下所示:

 1   <  a-pagination  v-model:current  ="pagination.current"  :total  ="pagination.total"  @change  ="change"   /> 

关于change事件功能,主要用于调用getStudents函数,如下所示:

 1  const change = (pagination) => {  2       var  no = formState.no;  3       var  name = formState.name;  4   getStudents(no, name);  5   console.log(pagination);  6  };

新增编辑功能

新增学生和编辑学生都是对单个学生实体进行操作,采用form表单进行提交到后台接口。其中visible用于控制弹窗的显示与隐藏。ok表示弹窗的确定事件。班级下拉框(a-select)显示班级列表,需要在加载页面时进行预加载。如下所示:

 1   <  a-modal  ref  ="modalRef"  v-model:visible  ="visible"  okText  ="保存"  cancelText  ="取消"  :wrap-style  ="{ overflow: 'hidden' }"  @ok  ="handleOk"  > 
 2       <  div  > 
 3           <  a-page-header  style  ="border: 1px solid rgb(235, 237, 240)"  title  ="学生管理"  sub-title  ="新增或编辑学生"   /> 
 4           <  a-form  :model  ="addEditFormState"  > 
 5               <  a-form-item  label  ="学号"  > 
 6                   <  a-input  v-model:value  ="addEditFormState.no"   /> 
 7               </  a-form-item  > 
 8               <  a-form-item  label  ="姓名"  > 
 9                   <  a-input  v-model:value  ="addEditFormState.name"   /> 
 10               </  a-form-item  > 
 11               <  a-form-item  label  ="年龄"  > 
 12                   <  a-input  v-model:value  ="addEditFormState.age"   /> 
 13               </  a-form-item  > 
 14               <  a-form-item  label  ="性别"  > 
 15                   <  a-radio-group  v-model:value  ="addEditFormState.sex"  > 
 16                       <  a-radio  :value  ="true"  ></  a-radio  > 
 17                       <  a-radio  :value  ="false"  ></  a-radio  > 
 18                   </  a-radio-group  > 
 19               </  a-form-item  > 
 20               <  a-form-item  label  ="班级"  > 
 21                   <  a-select  ref  ="select"  v-model:value  ="addEditFormState.classes"  style  ="width: 200px"  > 
 22                       <  a-select-option  :value  ="item.id"  v-for  ="(item) in dataClasses"  :key  ="item.id"  > {{item.name}} </  a-select-option  > 
 23                   </  a-select  > 
 24               </  a-form-item  > 
 25           </  a-form  > 
 26       </  div  > 
 27   </  a-modal  > 

新增编辑提交事件handleOk代码,其中根据id值判断是新增学生和编辑学生,如下所示:

 1  const handleOk = (e: MouseEvent) => {  2   console.log(e);  3   console.log(addEditFormState);  4       var  url = "" ;  5       if  (addEditFormState.id >0 ) {  6          url = "/api/Student/UpdateStudent";  //  编辑 
 7      }  else  {  8          url = "/api/Student/AddStudent";  //  新增 
 9   }  10   postD(url, {  11          "id": addEditFormState.id>0?addEditFormState.id: null  ,  12          "no" : addEditFormState.no,  13          "name" : addEditFormState.name,  14          "age" : addEditFormState.age,  15          "sex" : addEditFormState.sex,  16          "classesId" : addEditFormState.classes,  17          "createTime": "2022-08-15T15:31:12.224Z" ,  18          "createUser": 0 ,  19          "lastEditTime": "2022-08-15T15:31:12.224Z" ,  20          "lastEditUser": 0
 21      }).then(res => {  22   console.log(res);  23           if (res.status==200 ){  24               if (res.data==0 ){  25                  message.success('保存成功!' );  26                  visible.value =  false  ;  27                   var  no = formState.no;  28                   var  name = formState.name;  29   getStudents(no, name);  30              } else  {  31                  message.error('保存失败!' );  32   }  33   }  34   });  35      
 36  };

关于学生管理模块的全部代码,如下所示:



 1   <  template  > 
2 < a-page-header style ="border: 1px solid rgb(235, 237, 240)" title ="学生管理" sub-title ="学生信息基本操作" />
3 < a-form :model ="formState" name ="horizontal_query" layout ="inline" autocomplete ="off" @finish ="onFinish" @finishFailed ="onFinishFailed" >
4 < a-form-item label ="学号" name ="no" >
5 < a-input v-model:value ="formState.no" ></ a-input >
6 </ a-form-item >
7 < a-form-item label ="姓名" name ="name" >
8 < a-input v-model:value ="formState.name" ></ a-input >
9 </ a-form-item >
10 < a-form-item >
11 < a-button type ="primary" html-type ="submit" > 查询 </ a-button >
12 </ a-form-item >
13 < a-form-item >
14 < a-button type ="primary" @click ="addStudent" > 新增 </ a-button >
15 </ a-form-item >
16 </ a-form >
17 < a-table :columns ="columns" :data-source ="dataSource" bordered :pagination ="false" :row-key ="record => record.id" >
18 < template #bodyCell ="{ column, text, record }" >
19 < template v-if ="[ 'no','name', 'sge', 'dex','classesName'].includes(column.dataIndex)" >
20 < div > {{ text }} </ div >
21 </ template >
22 < template v-else-if ="column.dataIndex === 'operation'" >
23 < div class ="editable-row-operations" >
24 < a @click ="edit(record.key)" > Edit </ a >
25 </ div >
26 </ template >
27 </ template >
28 </ a-table >
29 < a-pagination v-model:current ="pagination.current" :total ="pagination.total" @change ="change" />
30 < a-modal ref ="modalRef" v-model:visible ="visible" okText ="保存" cancelText ="取消" :wrap-style ="{ overflow: 'hidden' }" @ok ="handleOk" >
31 < div >
32 < a-page-header style ="border: 1px solid rgb(235, 237, 240)" title ="学生管理" sub-title ="新增或编辑学生" />
33 < a-form :model ="addEditFormState" >
34 < a-form-item label ="学号" >
35 < a-input v-model:value ="addEditFormState.no" />
36 </ a-form-item >
37 < a-form-item label ="姓名" >
38 < a-input v-model:value ="addEditFormState.name" />
39 </ a-form-item >
40 < a-form-item label ="年龄" >
41 < a-input v-model:value ="addEditFormState.age" />
42 </ a-form-item >
43 < a-form-item label ="性别" >
44 < a-radio-group v-model:value ="addEditFormState.sex" >
45 < a-radio :value ="true" ></ a-radio >
46 < a-radio :value ="false" ></ a-radio >
47 </ a-radio-group >
48 </ a-form-item >
49 < a-form-item label ="班级" >
50 < a-select ref ="select" v-model:value ="addEditFormState.classes" style ="width: 200px" >
51 < a-select-option :value ="item.id" v-for ="(item) in dataClasses" :key ="item.id" > {{item.name}} </ a-select-option >
52 </ a-select >
53 </ a-form-item >
54 </ a-form >
55 </ div >
56 </ a-modal >
57 </ template >
58 < script lang ="ts" >
59 import { 60 defineComponent, 61 reactive, 62 toRefs, 63 ref, 64 toRaw 65 } from ' vue ' ; 66 import type { 67 UnwrapRef 68 } from ' vue ' ; 69 import { message } from ' ant-design-vue ' ; 70 import { 71 getD, 72 postD 73 } from ' ../api/index.js ' ; 74
75 const columns = [ 76 { 77 title: ' 学号 ' , 78 dataIndex: ' no ' , 79 key: ' no ' , 80 align: ' center ' , 81 width: ' 20% ' , 82 }, 83 { 84 title: ' 姓名 ' , 85 dataIndex: ' name ' , 86 标签: Javascript

添加新评论