在前面随笔《
循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理
》介绍了一个系统最初接触到的前端登录处理的实现,但往往对整个系统来说,一般会有很多业务对象,而每个业务对象的API接口又有很多,不过简单来说也就是常规的增删改查,以及一些自定义的接口,通用都比较有规律性。而本身我们这个VUE+Element 前端应用就是针对ABP框架的业务对象,因此前端的业务对象接口也是比较统一的,那么可以考虑在前端中对后端API接口调用进行封装,引入ES6的方式进行前端API的抽象简化。本篇随笔主要针对这个方面,介绍前端API接口的封装处理,以便简化我们大量类似的业务接口的累赘代码实现。

1、ABP框架API接口的回顾

ABP
是ASP.NET Boilerplate的简称,ABP是一个
开源
且文档友好的
应用程序框架
。ABP不仅仅是一个框架,它还提供了一个
最徍实践
的基于
领域驱动设计(DDD)
的体系结构模型。

启动Host的项目,我们可以看到Swagger的管理界面如下所示。

上图就是ABP后端框架的API接口的查看页面,从上图可以看到,一般业务对象,都有Get、GetAll、Create、Update、Delete等常见接口,由于这些接口是给前端进行调用的。

Vue + Element前端项目的视图、Store模块、API模块、Web API之间关系如下所示。

前面介绍了,一般前端调用,通过前端API类的封装,即可发起对后端API接口的调用,如系统登录API定义如下代码所示。

export functiongetInfo(id) {returnrequest({
url:
'/abp/services/app/User/Get',
method:
'get',
params: {
id
}
})
}

按照常规的API类的处理,我们对应的业务类,就需要定义很多这样的函数,如之前介绍产品信息处理的API接口一样。

由于常规的增删改查,都是标准的API接口,那么如果我们按照每个API类都需要重复定义这些API,显然不妥,太臃肿。

如果是常规的JS,那么就以公布函数方式定义API接口,不过我们可以引入ES6的处理方式,在JS中引入类和继承的概念进行处理相同的API接口封装。

2、基于ES6的JS业务类的封装

关于ES6,大家可以有空了解一下《
ES6 入门教程
》,可以全面了解ES6很多语法和相关概念。

不过这里只需要了解一下JS里面关于类的定义和继承的处理关系即可。

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过
class
关键字,可以定义类。

基本上,ES6 的
class
可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的
class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的
class
改写,就是下面这样。

class Point {
constructor(x, y) {
this.x =x;this.y =y;
}

toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}

上面代码定义了一个“类”,可以看到里面有一个
constructor
方法,这就是构造方法,而
this
关键字则代表实例对象。也就是说,ES5 的构造函数
Point
,对应 ES6 的
Point
类的构造方法。

Point
类除了构造方法,还定义了一个
toString
方法。注意,定义“类”的方法的时候,前面不需要加上
function
这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

Class 可以通过
extends
关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

class Point {
}

class ColorPoint extends Point {
}

上面代码定义了一个
ColorPoint
类,该类通过
extends
关键字,继承了
Point
类的所有属性和方法。

有了这些知识准备,那么我们来定义一个API接口的封装类,如下 base-api.js 代码所示。

//定义框架里面常用的API接口:Get/GetAll/Create/Update/Delete/Count等
export defaultclass BaseApi {
constructor(baseurl) {
this.baseurl =baseurl
}
//获取指定的单个记录 Get(data) {returnrequest({
url:
this.baseurl + 'Get',
method:
'get',
params: data
})
}
//根据条件获取所有记录 GetAll(data) {returnrequest({
url:
this.baseurl + 'GetAll',
method:
'get',
params: data
})
}
//创建记录 Create(data) {returnrequest({
url:
this.baseurl + 'Create',
method:
'post',
data: data
})
}
//更新记录 Update(data) {returnrequest({
url:
this.baseurl + 'Update',
method:
'put',
data: data
})
}
//删除指定数据 Delete(data) {returnrequest({
url:
this.baseurl + 'Delete',
method:
'delete',
params: data
})
}
//获取条件记录数量 Count(data) {returnrequest({
url:
this.baseurl + 'Count',
method:
'post',
data: data
})
}
}

以上我们定义了很多常规的ABP后端接口的封装处理,其中我们调用的地址通过组合的方式处理,而具体的地址则交由子类(业务对象API)进行赋值处理。

加入我们定义子类有DIctType、DictData等业务类,那么这些类继承BaseApi,就会具有相关的接口了,如下所示继承关系。

例如,我们对于DictDataApi的JS类定义如下所示。

通过一行代码 export default new Api('/abp/services/app/dictdata/') 就可以构造一个子类实例供使用了。

对于DictTypeApi来说,处理方式也是类似,继承自基类,并增加一些自己的接口实现即可。

这些API类的文件视图如下所示。

有了这些准备,我们就可以在视图页面类中导入这些定义,并使用JS类了。

//业务API对象
import dicttype from '@/api/dicttype'import dictdata from'@/api/dictdata'

加入我们要在视图页面中查询结果,直接就可以通过使用dictdata或者dicttype对象来实现对应的API调用,如下代码所示。

getlist() {//构造常规的分页查询条件
      var param ={
SkipCount: (
this.pageinfo.pageindex - 1) * this.pageinfo.pagesize,
MaxResultCount:
this.pageinfo.pagesize,//过滤条件 Name: this.searchForm.name,
Remark:
this.searchForm.remark,
DictType_ID:
this.searchForm.dictType_ID
};
//获取产品列表,绑定到模型上,并修改分页数量 this.listLoading = truedictdata.GetAll(param).then(data => {this.list =data.result.itemsthis.pageinfo.total =data.result.totalCountthis.listLoading = false})
}

或者如下代码所示。

    //删除指定字典类型
deleteDictType() {if (!this.searchForm.dictType_ID || typeof (this.searchForm.dictType_ID) === 'undefined') {return;
}
this.$confirm('您确认删除选定类型吗?', '操作提示',
{
type:
'warning' //success,error,info,warning //confirmButtonText: '确定', //cancelButtonText: '取消' }
).then(()
=>{var param = { id: this.searchForm.dictType_ID }
dicttype.Delete(param).then(data
=> {if(data.success) {//提示信息 this.$message({
type:
'success',
message:
'删除成功!'})//刷新数据 this.getTree();
}
})
})
}

最后我们来看看使用这些接口处理,对字典管理界面的实现。

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理


循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用


循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用


循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理


循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

VUE+Element 前端应用开发框架功能介绍

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

电商商品数据库的设计和功能界面的处理

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志

循序渐进VUE+Element 前端应用开发(32)--- 手机短信动态码登陆处理

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

使用代码生成工具快速开发ABP框架项目

使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理

使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题

标签: none

添加新评论