干货分享:一文掌握HarmonyOS Next网络请求开发
文章目录
前言
大家好,我是若城。本系列旨在帮助开发者快速实现HarmonyOS Next应用中的常用功能,提供即拿即用的代码示例。本文将重点介绍网络请求的封装与应用,让开发者能够轻松实现API接口调用。本系列不会过多讲解基础知识,需要申请权限的部分请开发者自行处理。
功能概述
本文将详细介绍:
- HTTP请求基础方法的封装
- 实用的HTTP请求工具类设计
- 类型定义与接口规范
- 实际应用场景演示
通过这些内容,开发者可以快速构建自己的网络请求层,并进行二次开发以满足项目需求, 好了,废话不多说,我们开始上课.
Request 工具类实现
文件位置
将以下代码保存为Request.ets
,放置在项目的utils目录下:
核心代码
下面是封装好的
Request.ets
代码可以直接拿走哦~~~
import { http } from \'@kit.NetworkKit\'import { promptAction, router } from \'@kit.ArkUI\'// 常量定义export const TOKEN_KEY: string = \'token\'export const BASE_URL: string = \'xxxxxx\' // 你的接口地址/** * API响应数据结构 */export class ResponsesData<T> { code: number = 0 msg: string = \"\" data: T | null = null}interface EmptyInterface {}/** * HTTP请求基础方法 * @param url 请求路径 * @param method 请求方法 * @param data 请求参数 * @returns Promise */async function requestHttp<T>(url: string = \'\', method: http.RequestMethod = http.RequestMethod.GET, data?: object): Promise<T> { // 创建HTTP请求实例 const httpRequest = http.createHttp() // 拼接完整URL let urlStr = BASE_URL + url // GET请求参数处理 if (method === http.RequestMethod.GET) { if (data && Object.keys(data).length) { const queryParams = Object.keys(data) .filter(key => data[key] !== undefined && data[key] !== null) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`) .join(\'&\') if (queryParams) { urlStr += \"?\" + queryParams } } } // 请求配置 const config: http.HttpRequestOptions = { method, readTimeout: 10000, // GET请求不需要传递extraData extraData: method === http.RequestMethod.GET ? \'\' : data || {} as EmptyInterface, header: { \'Content-Type\': \'application/json\', \"Authorization\": AppStorage.get(TOKEN_KEY) as string || \'\' } } try { // 发送请求 const res = await httpRequest.request(urlStr, config) console.info(`[HTTP ${method}] ${urlStr}`) // 处理HTTP状态码 switch (res.responseCode) { case 401: // 处理认证失败 AppStorage.set<string>(TOKEN_KEY, \'\') promptAction.showToast({ message: \'token超时!\' }) router.replaceUrl({ url: \'pages/Login/LoginPage\' }) return Promise.reject(new Error(\'token超时!\')) case 404: promptAction.showToast({ message: \'请求地址不正确!\' }) return Promise.reject(new Error(\'请求地址不正确!\')) default: // 解析响应数据 const result = JSON.parse(res.result as string) as ResponsesData<T> if (result.code === 200) { return result.data as T } else { promptAction.showToast({ message: result.msg || \'服务器异常!\' }) return Promise.reject(new Error(result.msg)) } } } catch (error) { promptAction.showToast({ message: `请求失败: ${error}` }) return Promise.reject(error) } finally { // 释放资源 httpRequest.destroy() }}/** * HTTP请求工具类 */export class Request { /** * GET请求 * @param url 请求路径 * @param data 请求参数 */ static get<T>(url: string, data?: object): Promise<T> { return requestHttp<T>(url, http.RequestMethod.GET, data) } /** * POST请求 * @param url 请求路径 * @param data 请求体 */ static post<T>(url: string, data?: object): Promise<T> { return requestHttp<T>(url, http.RequestMethod.POST, data) } /** * PUT请求 * @param url 请求路径 * @param data 请求体 */ static put<T>(url: string, data?: object): Promise<T> { return requestHttp<T>(url, http.RequestMethod.PUT, data) } /** * DELETE请求 * @param url 请求路径 * @param data 请求参数 */ static delete<T>(url: string, data?: object): Promise<T> { return requestHttp<T>(url, http.RequestMethod.DELETE, data) }}
数据类型定义
为了更好地管理数据结构,我们创建一个types.ets
文件来定义接口类型:
// 食物分类接口export interface Category { name: string; icon: Resource;}// 食物数据接口export interface FoodItem { name: string; img: string; calory: string;}// 常用食物数据接口export interface CommonFood { category: string; name: string; img: string; calory: string;}// 接口返回数据export interface ResponseData { keyword: string; Lists: FoodItem[]}
实战应用
在页面中使用网络请求
首先,导入必要的模块:
import { FoodItem, ResponseData } from \'../utils/types\';import { Request } from \"../utils/request\"
然后,实现搜索功能:
// 搜索功能searchFood(keyword: string): void { Request.get(`?key=xxxxxxx&food=${keyword}`).then(res => { console.log(\'搜索结果\', JSON.stringify(res)) this.searchResults = res.Lists router.pushUrl({ url: \"pages/SearchResult\", params: res.Lists }) })}
注意: 首页的页面代码以及相关内容可以参考上一节的文章哦,这里就不做展示啦~~
搜索结果页面实现
import { FoodItem, ResponseData } from \'../utils/types\';import { router, Router } from \'@kit.ArkUI\';@Entry@Componentstruct SearchResult { @State message: string = \'Hello World\'; @State searchResults: FoodItem[] = [] aboutToAppear(): void { const params = router.getParams() as FoodItem[] console.log(\"结果页\", JSON.stringify(params)) this.searchResults = params } build() { // 展示搜索结果 List() { ForEach(this.searchResults, (item: FoodItem) => { ListItem() { this.FoodItem(item) } }) } .width(\'100%\') .layoutWeight(1) .listDirection(Axis.Vertical) .edgeEffect(EdgeEffect.Spring) .padding({ top: 8, bottom: 16 }) .backgroundColor(\'#F8F8F8\') } @Builder FoodItem(item: FoodItem) { Column() { Row() { Image(item.img) .width(80) .height(80) .borderRadius(12) .backgroundColor(\'#F0F0F0\') .margin({ right: 16 }) .objectFit(ImageFit.Cover) .alt($r(\'app.media.food\')) Column() { Text(item.name) .fontSize(18) .fontWeight(FontWeight.Medium) .margin({ bottom: 8 }) .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) } .alignItems(HorizontalAlign.Start) .layoutWeight(1) .justifyContent(FlexAlign.Center) } .width(\'100%\') .padding(16) } .backgroundColor(Color.White) .borderRadius(16) .shadow({ radius: 8, color: \'rgba(0, 0, 0, 0.08)\', offsetY: 2 }) .margin({ bottom: 12, left: 16, right: 16 }) }}
效果展示
首页
搜索结果页
总结
本文介绍了如何在HarmonyOS Next应用中封装HTTP请求工具类,并通过实际案例展示了其使用方法。通过这种封装,我们可以大大简化网络请求的实现,提高代码的可维护性和可扩展性。希望这篇文章对你的HarmonyOS Next应用开发有所帮助!下课~~