当前位置: 首页 > news >正文

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • pdf文件怎么转换成ppt?介绍几种pdf转ppt的方法
  • 【洛谷】P9752 [CSP-S 2023] 密码锁
  • 自然语言处理系列六十九》搜索引擎项目实战》搜索框架技术选型
  • Linux环境常用的一些网络相关的命令
  • Java8的函数式编程简介
  • 切换淘宝最新npm镜像源
  • 整个场面要hold住-《分析模式》漫谈32
  • 【Rust练习】14.流程控制
  • 详细分析linux中的MySql跳过密码验证以及Bug(图文)
  • Vue3+TypeScript+Vite+Less 开发 H5 项目(amfe-flexible + postcss-pxtorem)
  • MySQL数据的增删改查(二)
  • git update-ref
  • Axure科技感大屏系统设计:智慧农场管理平台
  • TDengine 签约寓信科技,推动智慧公寓的数字化转型
  • 升级VMware
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • conda常用的命令
  • Github访问慢解决办法
  • HTTP请求重发
  • input的行数自动增减
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Otto开发初探——微服务依赖管理新利器
  • passportjs 源码分析
  • Python - 闭包Closure
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • Travix是如何部署应用程序到Kubernetes上的
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 关于Java中分层中遇到的一些问题
  • 入门级的git使用指北
  • 时间复杂度与空间复杂度分析
  • 使用Gradle第一次构建Java程序
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 我感觉这是史上最牛的防sql注入方法类
  • 我有几个粽子,和一个故事
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 协程
  • 学习Vue.js的五个小例子
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 《码出高效》学习笔记与书中错误记录
  • MyCAT水平分库
  • ​如何防止网络攻击?
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • (9)目标检测_SSD的原理
  • (HAL库版)freeRTOS移植STMF103
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)