HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (三、影视搜索页功能实现)

在HarmonyOS NEXT开发环境中,可以使用@nutpi/axios库来简化网络请求的操作。本文将展示如何使用HarmonyOS NEXT框架和@nutpi/axios库,从零开始实现一个简单的影视APP,主要关注影视搜索页的功能实现。

为什么选择@nutpi/axios

nutpi/axios是坚果派出品的,对axios封装过的鸿蒙HTTP客户端库,用于简化axios库的使用和以最简单的形式写代码。使用nutpi/axios库可以大大简化代码,使网络接口变得简单直观。

项目开源地址:https://atomgit.com/csdn-qq8864/hmmovie

好的作品是需要不断打磨,在你的学习和体验过程中有任何问题,欢迎到我的开源项目代码仓下面提交issue,持续优化。

安装nutpi/axios

首先,需要在项目中安装nutpi/axios库。

ohpm install @ohos/axios

在这里插入图片描述

实现电影搜索接口

使用nutpi/axios库来实现电影搜索接口。先封装一个工具类:

//axiosClient.ets
import {AxiosHttpRequest,HttpPromise} from '@nutpi/axios'
import {AxiosHeaders,AxiosRequestHeaders,AxiosError } from '@nutpi/axios';
import { Log } from './logutil';
import { promptAction } from "@kit.ArkUI";function showToast(msg:string){Log.debug(msg)promptAction.showToast({ message: msg })
}function showLoadingDialog(msg:string){Log.debug(msg)promptAction.showToast({ message: msg })
}function hideLoadingDialog() {}
/*** axios请求客户端创建*/
const axiosClient = new AxiosHttpRequest({baseURL: "http://120.27.146.247:8000/api/v1",timeout: 10 * 1000,checkResultCode: false,showLoading:true,headers: new AxiosHeaders({'Content-Type': 'application/json'}) as AxiosRequestHeaders,interceptorHooks: {requestInterceptor: async (config) => {// 在发送请求之前做一些处理,例如打印请求信息Log.debug('网络请求Request 请求方法:', `${config.method}`);Log.debug('网络请求Request 请求链接:', `${config.url}`);Log.debug('网络请求Request Params:', `\n${JSON.stringify(config.params)}`);Log.debug('网络请求Request Data:', `${JSON.stringify(config.data)}`);// 动态添加或修改header//config.headers['X-ATOMGIT-POP-COMMUNITY'] = 'openatom';axiosClient.config.showLoading = config.showLoadingif (config.showLoading) {showLoadingDialog("加载中...")}if (config.checkLoginState) {//let hasLogin = await StorageUtils.get(StorageKeys.USER_LOGIN, false)//Log.debug('网络请求Request 登录状态校验>>>', `${hasLogin.toString()}`);// if (hasLogin) {//   return config// } else {//   if (config.needJumpToLogin) {//     //Router.push(RoutePath.TestPage)//   }//   throw new AxiosError("请登录")// }}return config;},requestInterceptorCatch: (err) => {Log.error("网络请求RequestError", err.toString())if (axiosClient.config.showLoading) {hideLoadingDialog()}return err;},responseInterceptor: (response) => {//优先执行自己的请求响应拦截器,在执行通用请求request的if (axiosClient.config.showLoading) {hideLoadingDialog()}Log.debug('网络请求响应Response:', `\n${JSON.stringify(response.data)}`);if (response.status === 200) {// @ts-ignoreconst checkResultCode = response.config.checkResultCodeif (checkResultCode && response.data.errorCode != 0) {showToast(response.data.errorMsg)return Promise.reject(response)}return Promise.resolve(response);} else {return Promise.reject(response);}},responseInterceptorCatch: (error) => {if (axiosClient.config.showLoading) {hideLoadingDialog()}Log.error("网络请求响应异常", error.toString());errorHandler(error);return Promise.reject(error);},}
});function errorHandler(error: any) {if (error instanceof AxiosError) {//showToast(error.message)} else if (error != undefined && error.response != undefined && error.response.status) {switch (error.response.status) {// 401: 未登录// 未登录则跳转登录页面,并携带当前页面的路径// 在登录成功后返回当前页面,这一步需要在登录页操作。case 401:break;// 403 token过期// 登录过期对用户进行提示// 清除本地token和清空vuex中token对象// 跳转登录页面case 403://showToast("登录过期,请重新登录")// 清除token// localStorage.removeItem('token');break;// 404请求不存在case 404://showToast("网络请求不存在")break;// 其他错误,直接抛出错误提示default://showToast(error.response.data.message)}}
}export  {axiosClient,HttpPromise};

接口的实现很简单啦:

// 定义电影搜索接口
// 7.电影搜索接口
export const movieSearch =  (q:string,start:number,count:number): HttpPromise<SearchResp> => axiosClient.post({url:'/searchmovie',data: {  q:q,start:start,count:count }});

代码讲解

  1. 创建axios客户端:封装了一个axios客户端axiosClient工具类,并设置了基础URL和请求超时时间。
  2. 定义接口函数movieSearch函数接收三个参数:q(查询字符串)、start(起始位置)和count(数量),并返回一个Promise对象。

Search组件和List组件使用

接下来,将实现影视搜索页的组件,包括Search组件和List组件的使用。

import { movieSearch } from '../../common/api/movie';
import { SearchRespData } from '../../common/bean/SearchResp';
import { Log } from '../../utils/logutil';
import { BusinessError } from '@kit.BasicServicesKit';@Builder
export function SearchPageBuilder() {SearchPage()
}@Component
struct SearchPage {pageStack: NavPathStack = new NavPathStack()controller: SearchController = new SearchController()@State changeValue: string = ''@State submitValue: string = ''@State searchList: SearchRespData[] = []// 组件生命周期aboutToAppear() {Log.info('SearchPage aboutToAppear');}onPageShow(): void {this.controller.caretPosition(0)}build() {NavDestination() {Column({ space: 0 }) {Search({ controller: this.controller, value: this.changeValue, placeholder: '请输入片名' }).searchButton('搜索').width('95%').height(45).maxLength(30).backgroundColor('#F5F5F5').placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).textFont({ size: 14, weight: 400 }).focusable(true).defaultFocus(true).onSubmit((value: string) => {this.submitValue = value}).onChange((value: string) => {this.changeValue = valuemovieSearch(value, 1, 10).then((res) => {Log.debug(res.data.message)Log.debug("request", "res.data.code:%{public}d", res.data.code)if (res.data.code == 0) {this.searchList = res.data.data}}).catch((err: BusinessError) => {Log.debug("request", "err.data.code:%d", err.code)Log.debug("request", err.message)});}).margin({ left: 20, right: 20 })// list组件List({ space: 10 }) {ForEach(this.searchList, (item: SearchRespData, idx) => {ListItem() {Column({ space: 0 }) {Row() {Stack() {Image(item.cover).objectFit(ImageFit.Cover).borderRadius(5).zIndex(1)Text(item.year.substring(0, 10)).padding(5).margin({ top: 80 }).width('100%').height(20).textAlign(TextAlign.Center).maxLines(2).textOverflow({ overflow: TextOverflow.Clip }).fontSize(12).fontColor(Color.White).opacity(100) // 设置标题的透明度.backgroundColor('#808080AA') // 背景颜色设为透明.zIndex(2)}.width(100).height(100).margin({ left: 10 })Column({ space: 15 }) {Text(item.title).fontSize(16).fontWeight(FontWeight.Bold).align(Alignment.Start).width('100%')Text(item.genre).fontSize(12).align(Alignment.Start).width('100%')Text('评分: ' + item.rate).fontSize(12).align(Alignment.Start).width('100%')}.justifyContent(FlexAlign.Start).padding(5).margin({ left: 10 })}.size({ width: '100%', height: 100 })}.size({ width: '100%', height: 100 })}.onClick(() => {this.pageStack.pushDestinationByName("MovieDetailPage", { id: item.id }).catch((e: Error) => {console.log(`catch exception: ${JSON.stringify(e)}`)}).then(() => {// 跳转成功});})}, (itm: SearchRespData) => itm.id)}.divider({ strokeWidth: 2, color: '#F1F3F5' }).listDirection(Axis.Vertical).edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true })}.width('100%').height('100%')}.title("影视搜索").width('100%').height('100%').onReady(ctx => {this.pageStack = ctx.pathStack})}
}

代码讲解

  1. 导入模块:导入了之前定义的movieSearch函数,以及一些其他必要的模块。
  2. 定义组件状态
    • changeValue:用于存储当前搜索框中的输入值。
    • submitValue:用于存储用户提交的搜索值。
    • searchList:用于存储搜索结果的列表。
  3. 组件生命周期
    • aboutToAppear:组件即将出现在页面时执行的日志记录。
    • onPageShow:组件显示时重置光标位置。
  4. 构建页面
    • NavDestination:定义页面的导航目的地。
    • Column:垂直布局容器。
    • Search:搜索框组件,设置了搜索按钮、宽度、高度、最大长度等属性,并绑定了onSubmitonChange事件。
    • List:列表组件,用于显示搜索结果。
      • ForEach:遍历searchList数组,为每个搜索结果项创建一个ListItem
      • ListItem:列表项组件,包含电影的封面、年份、标题、类型和评分。
      • onClick:点击列表项时,导航到电影详情页。
  5. 列表样式
    • divider:设置列表项之间的分隔线。
    • listDirection:设置列表的方向为垂直。
    • edgeEffect:设置边缘效果为弹簧效果。

总结

通过本文,展示了如何使用HarmonyOS NEXT框架和nutpi/axios库来实现一个简单的影视搜索页。nutpi/axios库的使用大大简化了网络请求的操作,使代码更加简洁易读。希望这篇文章对你有所帮助,让你在开发HarmonyOS NEXT应用时更加得心应手。

如果你有任何问题或建议,欢迎在评论区留言交流!

作者介绍

作者:csdn猫哥

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

团队介绍

坚果派团队由坚果等人创建,团队拥有12个华为HDE带领热爱HarmonyOS/OpenHarmony的开发者,以及若干其他领域的三十余位万粉博主运营。专注于分享HarmonyOS/OpenHarmony、ArkUI-X、元服务、仓颉等相关内容,团队成员聚集在北京、上海、南京、深圳、广州、宁夏等地,目前已开发鸿蒙原生应用和三方库60+,欢迎交流。

版权声明

本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/893026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络IO与IO多路复用

一、网络IO基础 系统对象&#xff1a; 网络IO涉及用户空间调用IO的进程或线程以及内核空间的内核系统。例如&#xff0c;当进行read操作时&#xff0c;会经历两个阶段&#xff1a; 等待数据准备就绪。将数据从内核拷贝到进程或线程中。 多种网络IO模型的出现原因&#xff1a;…

天机学堂3-ES+Caffeine

文章目录 day05-问答系统表 用户端分页查询问题目标效果代码实现 3.6.管理端分页查询问题ES相关 管理端互动问题分页实现三级分类3.6.5.2.多级缓存3.6.5.3.CaffeineTODO&#xff1a;使用Caffeine作为本地缓存&#xff0c;另外使用redis或者memcache作为分布式缓存&#xff0c;构…

重拾Python学习,先从把python删除开始。。。

自己折腾就是不行啊&#xff0c;屡战屡败&#xff0c;最近终于找到前辈教我 第一步 删除Python 先把前阵子折腾的WSL和VScode删掉。还是得用spyder&#xff0c;跟matlab最像&#xff0c;也最容易入手。 从VScode上搞python&#xff0c;最后安装到appdata上&#xff0c;安装插…

智能新浪潮:亚马逊云科技发布Amazon Nova模型

在2024亚马逊云科技re:Invent全球大会上&#xff0c;亚马逊云科技宣布推出新一代基础模型Amazon Nova&#xff0c;其隶属于Amazon Bedrock&#xff0c;这些模型精准切入不同领域&#xff0c;解锁多元业务可能&#xff0c;为人工智能领域带来革新。 带你认识一起了解Amazon Nova…

flutter 装饰类【BoxDecoration】

装饰类 BoxDecoration BoxDecoration 是 Flutter 中用于控制 Container 等组件外观的装饰类&#xff0c;它提供了丰富的属性来设置背景、边框、圆角、阴影等样式。 BoxDecoration 的主要属性 1.color 背景颜色。类型&#xff1a;Color?示例&#xff1a; color: Colors.blu…

Datawhale-self-llm-Phi-4 Langchain接入教程

本项目是一个围绕开源大模型、针对国内初学者、基于 AutoDL 平台的中国宝宝专属大模型教程&#xff0c;针对各类开源大模型提供包括环境配置、本地部署、高效微调等技能在内的全流程指导&#xff0c;简化开源大模型的部署、使用和应用流程&#xff0c;让更多的普通学生、研究者…

某讯一面,感觉问Redis的难度不是很大

前不久&#xff0c;有位朋友去某讯面试&#xff0c;他说被问到了很多关于 Redis 的问题&#xff0c;比如为什么用 Redis 作为 MySQL 的缓存&#xff1f;Redis 中大量 key 集中过期怎么办&#xff1f;如何保证缓存和数据库数据的一致性&#xff1f;我将它们整理出来&#xff0c;…

Java技术栈 —— VMware WorkStation导入已有的虚拟机文件

Java技术栈 —— VMware WorkStation导入已有的虚拟机文件 FileInfo.com笔者转述 我下载了一个虚拟机镜像压缩包&#xff0c;解压之后&#xff0c;我发现了里面有五类文件&#xff0c;这五类文件的作用分别都是什么呢&#xff1f;哪个才是虚拟机文件的本体呢&#xff1f;要想自…

Python基于Django的图像去雾算法研究和系统实现(附源码,文档说明)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)

本文项目编号 T 141 &#xff0c;文末自助获取源码 \color{red}{T141&#xff0c;文末自助获取源码} T141&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

Ruby语言的循环实现

Ruby语言的循环实现深入探讨 在程序设计中&#xff0c;循环是一种常见的控制结构&#xff0c;用于重复执行某些代码块。不同的编程语言提供了不同类型的循环结构&#xff0c;以满足不同的需求。Ruby是一种灵活且易于使用的编程语言&#xff0c;其循环实现方式独具一格&#xf…

NVIDIA发布个人超算利器project digital,标志着ai元年的开启

上图NVIDIA公司创始人兼首席执行官 黄仁勋&#xff08;Jensen Huang&#xff09; 这些年被大家熟知的赛博朋克风格一直都是未来的代言词&#xff0c;可以承载人类记忆的芯片&#xff0c;甚至能独立思考的仿生人&#xff0c;现在&#xff0c;随着NVIDIA的project digital发布之后…

海云安开发者安全智能助手D10荣膺 “ AI标杆产品 ” 称号,首席科学家齐大伟博士入选2024年度 “ 十大杰出青年 ”

2024年12月27日&#xff0c;粤港澳大湾区AI领袖峰会在深圳成功举办&#xff0c;大会表彰了在人工智能技术创新、应用实践和产业发展等方面取得优异成绩的企业和个人&#xff0c;深圳海云安网络安全技术有限公司开发者安全智能助手D10荣膺“AI标杆产品”称号。同时&#xff0c;公…

ArkTS 组件事件、状态管理与资源管理

1. 组件事件 组件事件是在用户与界面交互时触发的操作&#xff0c;如点击、触碰、滑屏、按键等。在 ArkTS 中&#xff0c;通过为组件绑定事件处理函数&#xff0c;实现对用户交互的响应。 常用事件示例 事件类型描述示例onClick()点击事件Button().onClick(handler)onTouch(…

第23篇 基于ARM A9处理器用汇编语言实现中断<五>

Q&#xff1a;怎样修改HPS Timer 0定时器产生的中断周期&#xff1f; A&#xff1a;在上一期实验的基础上&#xff0c;可以修改按键中断服务程序&#xff0c;实现红色LED上的计数值递增的速率&#xff0c;主程序和其余代码文件不用修改。 实现以下功能&#xff1a;按下KEY0…

.Net 学习指南与资料分享

.NET学习资料 .NET学习资料 .NET学习资料 在当今数字化时代&#xff0c;软件开发领域蓬勃发展&#xff0c;.NET 作为微软推出的强大开发平台&#xff0c;凭借其出色的性能、跨平台特性以及丰富的生态系统&#xff0c;在企业级应用、Web 应用、移动应用等众多领域都有着广泛的…

Docker Desktop 中安装 MySQL 并开启远程访问的详细教程

是在 Docker Desktop 中安装 MySQL 并开启远程访问的详细教程&#xff1a; 一、安装 MySQL 容器 拉取 MySQL 镜像&#xff1a; docker pull mysql:latest这将从 Docker Hub 上拉取最新版本的 MySQL 镜像。如果你想使用特定版本的 MySQL&#xff0c;可以将 latest 替换为具体…

R语言绘图

多组火山图 数据准备&#xff1a; 将CSV文件同一在一个路径下&#xff0c;用代码合并 确保文件列名正确 library(fs) library(dplyr) library(tidyr) library(stringr) library(ggplot2) library(ggfun) library(ggrepel)# 获取文件列表 file_paths <- dir_ls(path &quo…

项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(六)

文章目录 一、考试管理模块实现1、添加考试功能实现1.1 页面设计1.2 前端功能实现1.3 后端功能实现1.4 效果展示2、考试管理功能实现2.1 页面设计2.2 前端功能实现2.3 后端功能实现2.3.1 后端查询接口实现2.3.2 后端编辑接口实现2.3.3 后端删除接口实现2.4 效果展示二、代码下载…

HTML中如何保留字符串的空白符和换行符号的效果

有个字符串 储值门店{{thing3.DATA}}\n储值卡号{{character_string1.DATA}}\n储值金额{{amount4.DATA}}\n当前余额{{amount5.DATA}}\n储值时间{{time2.DATA}} &#xff0c; HTML中想要保留 \n的换行效果的有下面3种方法&#xff1a; 1、style 中 设置 white-space: pre-lin…