在前面随笔《循序渐进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 function getInfo(id) {
return request({
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 default class BaseApi {
constructor(baseurl) {
this.baseurl = baseurl
} // 获取指定的单个记录
Get(data) {
return request({
url: this.baseurl + 'Get',
method: 'get',
params: data
})
} // 根据条件获取所有记录
GetAll(data) {
return request({
url: this.baseurl + 'GetAll',
method: 'get',
params: data
})
} // 创建记录
Create(data) {
return request({
url: this.baseurl + 'Create',
method: 'post',
data: data
})
} // 更新记录
Update(data) {
return request({
url: this.baseurl + 'Update',
method: 'put',
data: data
})
} // 删除指定数据
Delete(data) {
return request({
url: this.baseurl + 'Delete',
method: 'delete',
params: data
})
} // 获取条件记录数量
Count(data) {
return request({
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 = true
dictdata.GetAll(param).then(data => {
this.list = data.result.items
this.pageinfo.total = data.result.totalCount
this.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 前端应用开发(11)--- 图标的维护和使用

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

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

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

    在前面随笔<循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理>简单的介绍了一个结合ABP后端的登陆接口实现前端系统登陆的功能,本篇随笔继续深化这一主 ...

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

    在前面随笔<循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理>中介绍了用户管理模块的内容,包括用户列表的展示,各种查看.编辑.新增对话框的界面处理和后台数据处 ...

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

    在权限管理系统中,菜单也属于权限控制的一个资源,应该直接应用于角色,和权限功能点一样,属于角色控制的一环.不同角色用户,登录系统后,出现的系统菜单是不同的.在VUE+Element 前端中,我们菜单结 ...

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

    在一个业务管理系统中,如果我们需要实现权限控制功能,我们需要定义好对应的权限功能点,然后在界面中对界面元素的功能点进行绑定,这样就可以在后台动态分配权限进行动态控制了,一般来说,权限功能点是针对角色进 ...

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

    循序渐进VUE+Element 前端应用开发的系列文章中,前面介绍了系统各个功能的处理实现,本篇随笔从一个主线上介绍前后端开发的整合,让我们从ABP框架后端的查询接口的处理,前端API接口调用的封装, ...

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

    VUE+Element 前端应用,比较不错的一点就是界面组件化,我们可以根据重用的指导方针,把界面内容拆分为各个不同的组合,每一个模块可以是一个组件,也可以是多个组件的综合体,而且这一个过程非常方便. ...

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

    在我们使用Vue+Element开发前端的时候,往往涉及到很多界面组件的使用,其中很多直接采用Element官方的案例即可,有些则是在这个基础上封装更好利用.更少代码的组件:另外有些则是直接采用第三方 ...

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

    在我们一些系统里面,有时候会需要一些让用户自定义的数据信息,一般这些可以使用扩展JSON进行存储,不过每个业务表的显示项目可能不一样,因此需要根据不同的表单进行设计,然后进行对应的数据存储.本篇随笔结 ...

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

    在我们很多模块里面,都需要使用到一些诸如图片.Excel文件.PDF文件等附件的管理,一般我们倾向于把它独立为一个公用的附件管理模块,这样可以有效的统一管理附件的信息.本篇随笔介绍附件内容的管理,包括 ...

随机推荐

  1. Linux (四) 基础命令 下

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.查看文件内容 1.命令  cat 对应单词:concatenate 作用:查看文件内容 常用参数: ...

  2. Java实现 LeetCode 689 三个无重叠子数组的最大和(换方向筛选)

    689. 三个无重叠子数组的最大和 给定数组 nums 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为k,我们要使这3*k个项的和最大化. 返回每个区间起始索引的列表(索引从 0 ...

  3. Java实现 LeetCode 496 下一个更大元素 I

    496. 下一个更大元素 I 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nu ...

  4. Java实现 LeetCode 417 太平洋大西洋水流问题

    417. 太平洋大西洋水流问题 给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度."太平洋"处于大陆的左边界和上边界,而"大西洋"处于大陆的 ...

  5. Java实现 LeetCode 387 字符串中的第一个唯一字符

    387. 字符串中的第一个唯一字符 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. 案例: s = "leetcode" 返回 0. s = ...

  6. Java实现 LeetCode 329 矩阵中的最长递增路径

    329. 矩阵中的最长递增路径 给定一个整数矩阵,找出最长递增路径的长度. 对于每个单元格,你可以往上,下,左,右四个方向移动. 你不能在对角线方向上移动或移动到边界外(即不允许环绕). 示例 1: ...

  7. Java实现 LeetCode 299 猜数字游戏

    299. 猜数字游戏 你正在和你的朋友玩 猜数字(Bulls and Cows)游戏:你写下一个数字让你的朋友猜.每次他猜测后,你给他一个提示,告诉他有多少位数字和确切位置都猜对了(称为"B ...

  8. Java实现 LeetCode 228 汇总区间

    228. 汇总区间 给定一个无重复元素的有序整数数组,返回数组区间范围的汇总. 示例 1: 输入: [0,1,2,4,5,7] 输出: ["0->2","4-> ...

  9. Java实现 蓝桥杯VIP 算法提高 高精度乘法

    算法提高 高精度乘法 时间限制:1.0s 内存限制:256.0MB 问题描述 在C/C++语言中,整型所能表示的范围一般为-231到231(大约21亿),即使long long型,一般也只能表示到-2 ...

  10. Java实现蓝桥杯正则问题

    题目描述 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是 ...