在SqlSugar的開發框架的後端,我們基於Web API的封裝了統一的返回結果,使得WebAPI的介面返回值更加簡潔,而在前端,我們也需要統一對返回的結果進行解析,並獲取和Web API介面對應的數據進行展示即可,本篇隨筆介紹在Vue3+TypeScript+Vite的項目中,使用基於TypeSc... ...
在SqlSugar的開發框架的後端,我們基於Web API的封裝了統一的返回結果,使得WebAPI的介面返回值更加簡潔,而在前端,我們也需要統一對返回的結果進行解析,並獲取和Web API介面對應的數據進行展示即可,本篇隨筆介紹在Vue3+TypeScript+Vite的項目中,使用基於TypeScript的基類繼承的方式,實現對後端介面數據的統一解析處理的封裝操作。
1、SqlSugar的開發框架後端Web API的封裝
前面介紹到,在SqlSugar的開發框架的後端,我們需要對Web API統一封裝返回結果,如對於授權登錄的介面,我們的介面定義如下所示。
/// <summary> /// 登錄授權處理 /// </summary> /// <returns></returns> [AllowAnonymous] [HttpPost] [Route("authenticate")] public async Task<AuthenticateResultDto> Authenticate(LoginDto dto)
其中的Web API的返回結果定義如下所示。
/// <summary> /// 授權結果對象 /// </summary> public class AuthenticateResultDto { /// <summary> /// 令牌信息 /// </summary> public string? AccessToken { get; set; } /// <summary> /// 失效秒數 /// </summary> public int Expires { get; set; } /// <summary> /// 處理是否成功 /// </summary> public bool Succes { get; set; } /// <summary> /// 錯誤信息 /// </summary> public string? Error { get; set; } }
我們註意到 Authenticate 的Web API方法返回的結果是一些簡單的業務信息,一般我們返回結果需要在進行統一的封裝處理,以便達到統一的外部處理需要。
關於介面數據格式的統一封裝,我們定義一個WrapResultFilter,以及需要一個不封裝的屬性標識DontWrapResultAttribute,預設是統一封裝返回的結果。
而對於結果的統一封裝,我們只需要在Web API服務啟動的時候,加入相關的過濾器處理即可。
//控制器添加自定義過濾器 builder.Services.AddControllers(options=> { options.Filters.Add<WrapResultFilter>(); //統一結果封裝處理 options.Filters.Add<GlobalExceptionFilter>();//自定義異常處理 }); //所有控制器啟動身份驗證 builder.Services.AddMvc(options => { options.Filters.Add(new AuthorizeFilter());//所有MVC服務預設添加授權標簽 });
如下是Web API統一封裝後返回的結果對象。
而對於列表記錄的返回,同樣是進行了外圍的封裝。
/// <summary> /// 獲取所有記錄 /// </summary> [HttpGet] [Route("all")] [HttpGet]public virtual async Task<ListResultDto<TEntity>> GetAllAsync()
2、利用axios組件對後端API數據的訪問和基類的統一封裝處理
利用axios組件對後端Web API的調用,基本上是前端開發的標準做法了。
一般來說,我們為了方便,會對原生的axios組件進行一定的封裝處理,以便支持更好的調用處理,一般場景的操作就是POST、GET、PUT、DELETE,以及對文件流的上傳處理操作,axios的github地址是https://github.com/axios/axios,如果需要可以參考它來做封裝處理即可。
本篇隨筆基於https://github.com/vbenjs/vue-vben-admin 項目上的axios組件封裝進行使用,它對於axios組件的封裝比項目https://github.com/xiaoxian521/vue-pure-admin 上的封裝更加豐富一些,因此採用它。
利用axios組件,一般是為了方便,採用Typescript對它進行一定的封裝,並利於統一對Request和Response的對象統一攔截處理,如Request請求介面調用的時候,根據當前用戶的token進行頭部信息的註入,獲取到介面後,可以對結果內容進行拆解,獲得簡化後的結果。
例如對於常規的POST、GET、PUT、DELETE的處理,統一進行了調用,根據配置參數進行處理
get<T = any>( config: AxiosRequestConfig, options?: RequestOptions ): Promise<T> { return this.request({ ...config, method: "GET" }, options); } post<T = any>( config: AxiosRequestConfig, options?: RequestOptions ): Promise<T> { return this.request({ ...config, method: "POST" }, options); } put<T = any>( config: AxiosRequestConfig, options?: RequestOptions ): Promise<T> { return this.request({ ...config, method: "PUT" }, options); } delete<T = any>( config: AxiosRequestConfig, options?: RequestOptions ): Promise<T> { return this.request({ ...config, method: "DELETE" }, options); }
如對於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<number>(this.baseurl + "count", params); // } // POST 方法例子 // 創建對象 // async Create(data: object) { // return await this.HttpPost<boolean>(this.baseurl + `create`, data); // } // PUT 方法例子 // 更新對象 // async Update(data: object) { // return await this.HttpPut<boolean>(this.baseurl + `update`, data); // } // DELETE 方法例子 // 刪除指定ID的對象 // async Delete(id: number | string) { // return await this.HttpDelete<boolean>(this.baseurl + `${id}`); // } } // 構造客戶信息 Api實例,並傳遞業務類介面地址 export default new Api("/api/customer/");
如果需要一些定製的方法,我們則根據註釋的提示和Web API的路徑聲明進行編寫即可,如下是一個自定義介面的處理。
// 根據字典類型獲取對應的TreeNodeItem集合(包括id, label屬性) async GetTreeItemByDictType(dictTypeName: string) { return await this.HttpGet<TreeNodeItem[]>( this.baseurl + `treeitem-by-typename/${dictTypeName}` ); }
由於是基於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的相關技術點。
系列文章:
《基於SqlSugar的開發框架的循序漸進介紹(1)--框架基礎類的設計和使用》
《基於SqlSugar的開發框架循序漸進介紹(2)-- 基於中間表的查詢處理》
《基於SqlSugar的開發框架循序漸進介紹(3)-- 實現代碼生成工具Database2Sharp的整合開發》
《基於SqlSugar的開發框架循序漸進介紹(4)-- 在數據訪問基類中對GUID主鍵進行自動賦值處理 》
《基於SqlSugar的開發框架循序漸進介紹(5)-- 在服務層使用介面註入方式實現IOC控制反轉》
《基於SqlSugar的開發框架循序漸進介紹(6)-- 在基類介面中註入用戶身份信息介面 》
《基於SqlSugar的開發框架循序漸進介紹(7)-- 在文件上傳模塊中採用選項模式【Options】處理常規上傳和FTP文件上傳》
《基於SqlSugar的開發框架循序漸進介紹(8)-- 在基類函數封裝實現用戶操作日誌記錄》
《基於SqlSugar的開發框架循序漸進介紹(9)-- 結合Winform控制項實現欄位的許可權控制》
《基於SqlSugar的開發框架循序漸進介紹(10)-- 利用axios組件的封裝,實現對後端API數據的訪問和基類的統一封裝處理》
專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。轉載請註明出處:撰寫人:伍華聰 http://www.iqidi.com