微前端架构如何改变企业的开发模式与效率提升
780
2022-10-05
基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理
在SqlSugar的开发框架的后端,我们基于Web API的封装了统一的返回结果,使得WebAPI的接口返回值更加简洁,而在前端,我们也需要统一对返回的结果进行解析,并获取和Web API接口对应的数据进行展示即可,本篇随笔介绍在Vue3+TypeScript+Vite的项目中,使用基于TypeScript的基类继承的方式,实现对后端接口数据的统一解析处理的封装操作。
1、SqlSugar的开发框架后端Web API的封装
前面介绍到,在SqlSugar的开发框架的后端,我们需要对Web API统一封装返回结果,如对于授权登录的接口,我们的接口定义如下所示。
///
其中的Web API的返回结果定义如下所示。
///
我们注意到 Authenticate 的Web API方法返回的结果是一些简单的业务信息,一般我们返回结果需要在进行统一的封装处理,以便达到统一的外部处理需要。
关于接口数据格式的统一封装,我们定义一个WrapResultFilter,以及需要一个不封装的属性标识DontWrapResultAttribute,默认是统一封装返回的结果。
而对于结果的统一封装,我们只需要在Web API服务启动的时候,加入相关的过滤器处理即可。
//控制器添加自定义过滤器builder.Services.AddControllers(options=>{ options.Filters.Add
如下是Web API统一封装后返回的结果对象。
而对于列表记录的返回,同样是进行了外围的封装。
///
2、利用axios组件对后端API数据的访问和基类的统一封装处理
利用axios组件对后端Web API的调用,基本上是前端开发的标准做法了。
一般来说,我们为了方便,会对原生的axios组件进行一定的封装处理,以便支持更好的调用处理,一般场景的操作就是POST、GET、PUT、DELETE,以及对文件流的上传处理操作,axios的github地址是 config: AxiosRequestConfig, options?: RequestOptions ): Promise
如对于HTTP请求拦截,我们需要在配置信息中加入token令牌信息,如下代码所示。
/** * @description: 请求-处理 */ requestInterceptors: (config, options) => { // 请求之前处理config const tokenString = getToken(); // console.log(tokenString); if (tokenString) { const data = JSON.parse(tokenString) as AuthenticateDto; const now = new Date().getTime(); const expired = parseInt(data.expires) - now <= 0; // console.log(data, now, expired); if (expired) { // token过期刷新 } const token = data.accessToken; if ( token && (config as Recordable)?.requestOptions?.withToken !== false ) { // jwt token (config as Recordable).headers.Authorization = options.authenticationScheme ? `${options.authenticationScheme} ${token}` : token; } } return config; },
这些我们进行一定的微调即可,大多数情况下,不需要进行太多的设置。
对于统一返回的结果,我们为了方便,统一进行了处理。在前端定义好几个数据类型,最后返回结果result即可。
在以前写过的关于前端Web API的处理文章中,有《循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合》 、《在Bootstrap开发框架基础上增加WebApi+Vue&Element的前端》,都是对相关业务类进行接口的抽象封装,以便于重用服务器的逻辑调用。
Vue&Element的前端的架构设计如下所示。
一般来说,我们页面模块可能会涉及到Store模块,用来存储对应的状态信息,也可能是直接访问API模块,实现数据的调用并展示。在页面开发过程中,多数情况下,不需要Store模块进行交互,一般只需要存储对应页面数据为全局数据状态的情况下,才可能启用Store模块的处理。
通过WebProxy代理的处理,我们可以很容易在前端中实现跨域的处理,不同的路径调用不同的域名地址API都可以,最终转换为本地的API调用,这就是跨域的处理操作。
3、访问后端接口的ES6 基类的封装处理
前端根据框架后端的接口进行前端JS端的类的封装处理,引入了ES6类的概念实现业务基类接口的统一封装,简化代码。
权限模块我们涉及到的用户管理、机构管理、角色管理、菜单管理、功能管理、操作日志、登录日志等业务类,那么这些类继承BaseApi,就会具有相关的接口了,如下所示继承关系。
按照这个思路,我们在BaseApi的ES6类里面定义了对应Web API基类里面的操作方法,如下所示。
这样,我们在创建一个业务类的时候,如果没有特殊的自定义接口,只需要继承基类BaseApi即可具有所有的常规基类方法了。
// 导入API基类对象,默认具有Get/GetAll/Create/Update/Delete/BatchDelete/SaveImport/Count等接口import BaseApi from "./base-api";// 业务类自定义接口实现, 通用的接口已经在BaseApi中定义class Api extends BaseApi { // 参考下面案例,增加自定义函数 // GET 方法例子 // 根据条件计算记录数量 // async GetCount(params: object) { // return await this.HttpGet
// 根据字典类型获取对应的TreeNodeItem集合(包括id, label属性) async GetTreeItemByDictType(dictTypeName: string) { return await this.HttpGet
由于是基于TypeScript,我们在具体的位置中定义了TreeNodeItem类型,对应服务器返回的WebAPI类型即可。
//树节点类型export interface TreeNodeItem { id: string; label: string; key?: string; children?: TreeNodeItem[];}
然后在自定义的ES6类的顶部引入类型定义就可以了
import { PagedResult, ListResult, TreeNodeItem, CListItem, CommonResult} from "./types";
我们定义了接口后,就可以在Vue的JS里面进行调用了。
// 使用字典类型,从服务器请求数据await dictdata.GetTreeItemByDictType(typeName).then(list => { if (list) { list.forEach(item => { dictItems.value.push({ id: item.id, label: item.label }); }); }});
我们也可以使用async/await的异步线程调用方法,如下所示。
另外,由于我们的ES6接口定义,是基于TypeScript的,它的数据类型可以推断出来,因此在编码或者查看对应属性的时候,会有非常好的提示信息,如上所示。
最后我们来验证下实际的axios调用页面的效果。
以及另外一个复杂一点的测试页面展示。
后续继续介绍Vue3+TypeScript+ElementPlus的相关技术点。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~