您的位置:首页 > 娱乐 > 明星 > HarmonyOS开发5.0【封装request泛型方法】axios

HarmonyOS开发5.0【封装request泛型方法】axios

2024/12/27 22:13:49 来源:https://blog.csdn.net/2301_76813281/article/details/142151325  浏览:    关键词:HarmonyOS开发5.0【封装request泛型方法】axios

一 准备工作

1. 先开启一下虚拟机的权限

src/main/module.json5 打开module.json5在15~19行 进行配置网络权限

1

2. 在终端下载安装一下 ohpm install @ohos/axios

复制 粘贴进去回车就行

2

3. 这样显示就是安装好了

如果导入不行就关了重新启动

3

二 创建一个ETS文件,利用静态的泛型方法对axios模块进行统一请求封装(方法名:reqeust,兼容get和post)

axios.reqeust()方法中请求参数提炼和响应泛型提炼

import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from'@ohos/axios'
import { iResponseModel } from '../models/datamodel'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = errreturn Promise.reject(errObj.message) // 外面使用者使用try{}catch(err){}}}
}

三 增加toke携带和处理非10000的逻辑状态码的响应结果(接口响应正常,但是有逻辑异常,比如用户名或者密码错误)

import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction } from '@kit.ArkUI'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}// 3. 在请求前在header中携带token// 获取tokenlet user = AppStorage.get<iLoginUserModel>('user')if (user && user.token) {reqConfig.headers = {'Authorization': `Bearer ${user.token}`}}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)// 4. 处理服务器响应体中的code值为非10000的情况if (res.data.code != 10000) {//  将服务器的逻辑问题信息提示给用户promptAction.showToast({ message: res.data.message })return Promise.reject(res.data.message)  //传递给外部调用者的 catch()中的信息}//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = errreturn Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}}}
}

四 在try{}catch(err){}的catch里面处理状态码为401的时跳转到登录页面,其他状态码时提示用户 errObj.response?.status == 401

import { promptAction, router } from '@kit.ArkUI'
import axios, { AxiosResponse, AxiosError } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { HdHttp } from '../utils/request'interface iReqBody {username: stringpassword: string
}@Entry
@Component
struct LoginPage {@State username: string = 'yu123'@State password: string = 'yu123456'@State isAgree: boolean = false@State islogin: boolean = false// 负责登录async login() {// 1. 参数合法性检查/** ● 能对用户名和密码文本框做非空验证处理● 对用户协议勾选做验证处理* */if (this.username == '' || this.password == '') {return promptAction.showToast({ message: '用户名和密码必填' })}if (!this.isAgree) {promptAction.showToast({ message: '请先勾选协议' })this.isAgree = truereturn}// 2. axios请求服务器接口this.islogin = truetry {let reqBody = new Object({username: this.username,password: this.password})let res = await HdHttp.request<iLoginUserModel>('POST', 'hm/login', reqBody)this.islogin = false// 3. 处理服务器响应回来的报文体的数据//   3.1 判断服务器响应体中的code==10000的时候才保存数据,否则提示用户响应体中的message// if (res.data.code != 10000) {//   return promptAction.showToast({ message: res.data.message })// }// 3.2 将服务器响应回来的数据保存到AppStroage中,保存的数据类型是iLoginUserModelAppStorage.setOrCreate('user', res.data)// 4. 跳转到首页router.replaceUrl({ url: 'pages/Index' })} catch (err) {this.islogin = false// 将来服务器的状态码是非200的,就会自动触发catchlet errObj: AxiosError = err //最终将err大错误对象,转为AxiosErrorAlertDialog.show({ message: errObj.message }) //最后提示给用户的是message字符串}}build() {Column() {// logoColumn({ space: 10 }) {Image($r('app.media.icon')).height(55).aspectRatio(1)}.margin({ top: 170 })//  登录区域Column({ space: 20 }) {TextInput({ text: $$this.username }).backgroundColor(Color.White).width('90%').borderRadius(0)TextInput({ text: $$this.password }).type(InputType.Password).backgroundColor(Color.White).width('90%')Row() {Checkbox().select(this.isAgree).selectedColor('#FA6D1D').onChange(value => {this.isAgree = value})Text('已阅读并同意').fontSize(14).fontColor($r('app.color.ih_gray_color')).padding({ right: 4 })Text('用户协议').fontSize(14).padding({ right: 4 })Text('和').fontSize(14).fontColor($r('app.color.ih_gray_color')).padding({ right: 4 })Text('隐私政策').fontSize(14).onClick(() => {router.pushUrl({url: 'pages/PreviewWebPage'})})}.width('90%')Button({ type: ButtonType.Normal }) {Row() {if (this.islogin) {LoadingProgress().height(28).aspectRatio(1).color(Color.White)}Text('登录')}}.borderRadius(4).width(328).height(45).fontColor(Color.White).linearGradient({angle: 135,colors: [['#FCA21C', 0],['#FA6D1D', 1]]}).onClick(() => {this.login()})}.margin({ top: 50 })}.width('100%').height('100%')}
}
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction, router } from '@kit.ArkUI'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}// 3. 在请求前在header中携带token// 获取tokenlet user = AppStorage.get<iLoginUserModel>('user')if (user && user.token) {reqConfig.headers = {'Authorization': `Bearer ${user.token}`}}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)// 4. 处理服务器响应体中的code值为非10000的情况if (res.data.code != 10000) {//  将服务器的逻辑问题信息提示给用户promptAction.showToast({ message: res.data.message })return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息}//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = err// 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面if (errObj.response?.status == 401) {promptAction.showToast({ message: '登录已失效,请重新登录' })router.replaceUrl({ url: 'pages/LoginPage' })} else {//  提示用户是什么错误即可promptAction.showToast({ message: '网络异常:' + errObj.message })}// AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}}}
}

五 提炼单独的POST < T > 和 GET< T >来简化对上一步封装好的reqeust方法的调用

封装完成 完整版

import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction, router } from '@kit.ArkUI'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {// 这个方法给外面专门做get请求调用的static async Get<T>(url: string, paramsOrData?: object) {return await HdHttp.request<T>('GET', url, paramsOrData)}// 这个方法给外面专门做post请求调用的static async Post<T>(url: string, paramsOrData?: object) {return await HdHttp.request<T>('POST', url, paramsOrData)}/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */private static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}// 3. 在请求前在header中携带token// 获取tokenlet user = AppStorage.get<iLoginUserModel>('user')if (user && user.token) {reqConfig.headers = {'Authorization': `Bearer ${user.token}`}}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)// 4. 处理服务器响应体中的code值为非10000的情况if (res.data.code != 10000) {//  将服务器的逻辑问题信息提示给用户promptAction.showToast({ message: res.data.message })return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息}//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = err// 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面if (errObj.response?.status == 401) {promptAction.showToast({ message: '登录已失效,请重新登录' })router.replaceUrl({ url: 'pages/LoginPage' })} else {//  提示用户是什么错误即可promptAction.showToast({ message: '网络异常:' + errObj.message })}// AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}}}
}

总结

以上是我在项目中的用到的关于 axios 的一些封装方法。

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

2

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!
3

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com