HarmonyOS NEXT应用开发实战(封装比UniApp和小程序更简单好用的网络库)

2024-10-17 08:49:07
127次阅读
0个评论

HarmonyOS NEXT应用开发实战(封装比UniApp和小程序更简单好用的网络库)

网络访问接口,使用频次最高。之前习惯了uniapp下的网络接口风格,使用起来特别的简单方便。转战到鸿蒙上后,原始网络接口写着有些繁琐,不封装的话写着不快。博主借鉴uniapp平台下网络访问库的实现,封装实现了适合鸿蒙平台的网库库,目标让鸿蒙上网络接口使用,简单程度比肩uniapp,比Axios更轻量级。源码开源,代码量也不多,但更方便定制优化,功能一点儿也不弱。

前言

接博主上篇文章HarmonyOS NEXT应用开发(一、打造最好用的网络通信模块组件),​​​​​​网络库已经封装好啦,成功发布到了OpenHarmony三方库中心仓。地址:[https://ohpm.openharmony.cn/#/cn/detail/@yyz116%2Fh_request]

但是刚发布还没人气,可能一些小伙伴不会用。这里特写了篇文章和使用demo,发出来让大家看下,原来写网络接口竟可以如此简单。

有多简单?demo源码地址:zhihudaily: HarmonyOS NEXT 项目开发实战,仿知乎日报的实现

看以下接口示例:

首先项目中先引入我发布到鸿蒙中心仓库的h_request网络库:

"dependencies": {
    "@yyz116/h_request": "1.0.1"
  }

//main/ets/common/api/home.ts
import { setRequestConfig } from '../../utils/http';
import { BaseResponse,SwiperData,HotMovieReq,MovieRespData } from '../bean/ApiTypes';
 
// 调用setRequestConfig函数进行请求配置
setRequestConfig();
 
const http = globalThis.$http;
 
// 获取轮播图api接口
export const getSwiperList = (): Promise<BaseResponse<SwiperData>> => http.get('/swiperdata');
 
// 获取热门影视接口
export const getHotMovie = (req:HotMovieReq): Promise<BaseResponse<MovieRespData>> => http.post('/hotmovie',req);
 

以上home.ts的首页相关的api接口中,两行代码就写好了两个接口,够简单清晰吧。一个是获取影视轮播图的get接口,一个是获取影视数据的post接口请求。

详细示例

接口实现

准备两个后台接口:

### 1.首页,影视轮播图
get http://175.178.126.10:8000/api/v1/swiperdata
 
### 2.首页,正在热映的电影
post http://175.178.126.10:8000/api/v1/hotmovie
Content-Type:application/json
 
{
    "start": 0,
    "count": 1,
    "city": "郑州"
}

在项目工程源码ets/main/common/bean/目录下,创建网络通信json包协议的type定义:

//file:ApiTypes.ts
export interface BaseResponse<T>{
  status: number;
  statusText:string;
  data:T;
}
 
export interface ErrorResponse {
  code: number;
  message: string;
  data: [];
}
 
// 轮播图响应数据
export interface SwiperItem{
  id:string;
  imageUrl:string;
  title:string;
  url:string;
  description:string;
}
export interface SwiperData {
  code: number;
  message: string;
  data: Array<SwiperItem>;
}
 
// 热门影视请求数据
export interface HotMovieReq {
  start: number;
  count: number;
  city:string;
}
// 热门影视响应数据
interface MovieItem{
  id:string;
  cover:string;
  title:string;
  gener:string;
  rate:number;
}
export interface MovieRespData {
  code: number;
  message: string;
  data: Array<MovieItem>;
  count: number;
  start: number;
  total: number;
  title: string;
}

创建个utils文件夹,放置封装的http.ts工具类,这个主要用来配置全局后台服务地址,参数和设置全局拦截器,并把其网络请求实例挂载在ArkTS引擎实例内部的一个全局对象globalThis中,供全局使用。

import Request, { HttpRequestConfig, HttpResponse } from '@yyz116/h_request'
import { Log } from './logutil';

const $u = {
  http: new Request(),
}
//挂载在ArkTS引擎实例内部的一个全局对象globalThis中,供全局使用
globalThis.$http = $u.http;

export const setRequestConfig = () => {
  globalThis.$http.setConfig((config:HttpRequestConfig) => {
    config.baseURL = "http://175.178.126.10:8000/api/v1";
    return config;
  });
  // 请求拦截
  globalThis.$http.interceptors.request.use(
    (config) => {
      Log.debug('请求拦截')
      return config
    },
    (error) => {
      return Promise.reject(error)
    }
  )
  // 响应拦截
  globalThis.$http.interceptors.response.use(
    (response:HttpResponse) => {
      Log.debug('响应拦截')
      if (response.data.code == 401) {
        // 提示重新登录
        console.log('请登录')
        setTimeout(() => {
          console.log('请请登录')
        }, 1000);
      }
      return response
    },
    (error) => {
      return Promise.reject(error)
    }
  )
}

上述拦截器可以根据需要定制,接下来就是写接口啦,以下示例一个是get接口使用,一个是post接口使用,且带post的数据。

import { setRequestConfig } from '../../utils/http';
import { BaseResponse,SwiperData,HotMovieReq,MovieRespData } from '../bean/ApiTypes';
 
// 调用setRequestConfig函数进行请求配置
setRequestConfig();
 
const http = globalThis.$http;
 
// 获取轮播图api接口
export const getSwiperList = (): Promise<BaseResponse<SwiperData>> => http.get('/swiperdata');
 
// 获取热门影视接口
export const getHotMovie = (req:HotMovieReq): Promise<BaseResponse<MovieRespData>> => http.post('/hotmovie',req);
 

如果get的接口,带参数呢?带参数的话可以这样写:

// 发送get请求,带参数,实际请求为:xxx.xxx/api/v1/musicsearchlrc?id=""&kind=""
http.get('api/v1/musicsearchlrc', {params:{id:"543656129",kind:"wy"}}).then((res:HttpResponse<Result>) => {
              hilog.debug(0x0000,"request",res.data.message)
              hilog.debug(0x0000,"request","res.data.code:%{public}d",res.data.code)
            }).catch((err:HttpResponse<Error>) => {
              hilog.debug(0x0000,"request","err.data.code:%d",err.data.code)
              hilog.debug(0x0000,"request",err.data.message)
            });
          })

如何使用

以上简单的两行代码就写好了两个接口。接下来就可以在页面中愉快的使用啦,可以看到使用变得十分简单。

示例如下:

import {getSwiperList,getHotMovie} from "../common/api/home"
import { hilog } from '@kit.PerformanceAnalysisKit';
import { ErrorResponse } from '../common/bean/ApiTypes';
 
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageShow() {
    console.info('Index onPageShow');
  }
  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageHide() {
    console.info('Index onPageHide');
  }
 
  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onBackPress() {
    console.info('Index onBackPress');
  }
 
  // 组件生命周期
  aboutToAppear() {
    console.info('MyComponent aboutToAppear');
  }
 
  // 组件生命周期
  aboutToDisappear() {
    console.info('MyComponent aboutToDisappear');
  }
 
  build() {
    Row() {
      Column() {
        Text(this.message)
          .id('HelloWorld')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
 
        Button('test')
          .onClick(() => {
            console.info('button click');
            getSwiperList().then((res) => {
              hilog.debug(0x0000,"request",res.data.message)
              hilog.debug(0x0000,"request","res.data.code:%{public}d",res.data.code)
              hilog.debug(0x0000,"request","res.data.data[0]:%{public}s",res.data.data[0].id)
              hilog.debug(0x0000,"request","res.data.data[0]:%{public}s",res.data.data[0].imageUrl)
              hilog.debug(0x0000,"request","res.data.data[0]:%{public}s",res.data.data[0].title)
            }).catch((err:ErrorResponse) => {
              hilog.debug(0x0000,"request","err.data.code:%d",err.code)
              hilog.debug(0x0000,"request",err.message)
            });
 
            getHotMovie({start:0,count:1,city:"郑州"}).then((res) => {
              hilog.debug(0x0000,"request",res.data.message)
              hilog.debug(0x0000,"request","res.data.code:%{public}d",res.data.code)
              hilog.debug(0x0000,"request","res.data.data[0]:%{public}s",res.data.data[0].id)
              hilog.debug(0x0000,"request","res.data.data[0]:%{public}s",res.data.data[0].gener)
              hilog.debug(0x0000,"request","res.data.data[0]:%{public}s",res.data.data[0].title)
            }).catch((err:ErrorResponse) => {
              hilog.debug(0x0000,"request","err.data.code:%d",err.code)
              hilog.debug(0x0000,"request",err.message)
            });
          })
      }
      .height('100%')
      .width('100%')
    }
  }
}

总结

以上就是笔者封装的鸿蒙开源库h_request的使用介绍。可以看出使用此网络封装库后,在鸿蒙的网络接口开发上,也可以体验到如uniapp小程序开发般的简单易用。分享给有需要的小伙伴,欢迎留言评论并提宝贵意见!

最终目标,打造出一个在鸿蒙平台上最简单好用的网络库,让写网络接口变成一种享受。随着互联网巨头支付宝和微信的接入适配,HarmonyOS Next已经稳啦,期待更多的小伙伴们加入鸿蒙生态,跟随时代潮流,为国产化替代贡献力量。

写在最后

最后,推荐下笔者的业余开源app影视项目“爱影家”,推荐分享给与我一样喜欢免费观影的朋友。 【注:该项目仅限于学习研究使用!请勿用于其他用途!】

开源地址:爱影家app开源项目介绍及源码

https://gitee.com/yyz116/imovie

原文链接:https://blog.csdn.net/yyz_1987/article/details/142799029

收藏00

登录 后评论。没有帐号? 注册 一个。