欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > 【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十八)

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十八)

2024/10/24 19:29:37 来源:https://blog.csdn.net/youyoufenglai/article/details/138356874  浏览:    关键词:【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十八)

课程地址: 黑马程序员HarmonyOS4+NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发

(本篇笔记对应课程第 28 节)

P28《27.网络连接-Http请求数据》

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

案例:

在这里插入图片描述

这里不懂后端假设服务器的前端小伙伴就需要课程源码资料了,在课程说明里有获取课程资料的方法,我按照说明获取了如下链接:

黑马《HarmonyOS4.0开发应用从入门到实战》
在线学习:
https://www.bilibili.com/video/BV1Sa4y1Z7B1/
网盘链接:
https://pan.baidu.com/s/1EKJct0IoPRHQXboKrG4TCw?pwd=9988
提取码:9988

成功提取了课程相关资料~

新建一个页面路由;执行相关命令启动服务器:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ShopPage.ets 文件中的代码如下:

在这里插入图片描述

在这里插入图片描述

商店列表数组的数据类型是 ShopInfo 类型,由于这是与页面视图渲染相关的数据,该类型定义在 viewmodel 目录下的一个 ts 文件中:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

页面渲染部分即build函数中的代码如下:

在这里插入图片描述

在这里插入图片描述

子组件 ShopItem.ets 中的代码如下:

在这里插入图片描述

其中,Text 的 ellipsisTextOverFlow 属性已不存在,查看文档,发现已替换为了以下属性:在这里插入图片描述

新建 model 文件夹,其中的文件用于处理数据,在其中新建 ShopModel.ts 文件,在这个文件中获取商铺列表数据:

在这里插入图片描述

在这里插入图片描述

由于 request 方法返回的是一个 Promise ,通过这个请求获取到的 ShopInfo类型的数据是异步的,所以需要将 getShopList 方法的返回值写成 Promise 类型(Line 8),同时将方法中的http请求过程封装成返回一个Promise:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

使用这个调用接口的方法:

在这里插入图片描述

下滑加载更多效果:添加 onReachEnd 函数,由于下滑触底时有回弹动画效果,会导致该触底函数被触发两次,因此增加一个 isLoading 变量来进行控制(实践中发现该问题好像不存在了):

在这里插入图片描述

在这里插入图片描述

此时再次观察上滑效果, “触底” 会触发 2 次,但加载数据只触发 1次,正是我们想要的效果。

增加翻页与查询效果:

在这里插入图片描述

此时发现问题,上滑查询下一页数据后,将之前的数据替换掉了,这是因为我们直接将新查询到的数据赋值给了 this.shops,应该改为将新查询到的数据追加到 this.shops 中;同时在查询成功后将 isLoading 的值改回false, 不然只会查询一次。

在这里插入图片描述

没有新的数据后,触底时仍然会请求数据,不合理。增加 isMore 变量控制,初始为true,没有更多数据后不再请求。

在这里插入图片描述

在这里插入图片描述

实践:

按照视频中的页面效果与代码,写好静态页面。过程中遇到如下报错:

在这里插入图片描述

猜测是图片问题,但具体什么问题,不知晓。只好问度娘咯。

在这里插入图片描述

找到解析同款报错的这篇文章:DevEco Studio 报错only contain [a-zA-z0-9_].

在这里插入图片描述

将图片名字改为 1_1 后报错消失。

鸿蒙中这个数组[ r ( ′ a p p . m e d i a . 1 1 ′ ) , r('app.media.1_1'), r(app.media.11),r(‘app.media.1_2’)]怎么定义类型?(不太懂,待解决)

在这里插入图片描述

在这里插入图片描述

暂时 ignore 了

在这里插入图片描述

// ShopPage.etsimport { Header } from '../components/CommonComponents'
import ShopInfo from '../viewmodel/ShopInfo'
import ShopItem from '../views/ShopItem'@Entry
@Component
struct ShopPage {@State shops: ShopInfo[] = []aboutToAppear(){// 加载商品数据this.loadShopInfo()}build() {Column({space:10}) {Header({title:'商铺列表'})List({space:10}){ForEach(this.shops, shop=>{ListItem(){ShopItem({shop:shop})}})}.padding({left:14,right:14})}.width('100%').height('100%').backgroundColor('#efefef')}loadShopInfo(){// TODO 加载数据let shops = [{id:1,name:'新白鹿餐厅(运河上街店)',images:[$r('app.media.1_1'),$r('app.media.1_2')],area:'运河上街',address:'台州路运河上街购物中心F5',avgPrice:61,comments:8045,score:47,openHours:'10:39-21:00'},{id:2,name:'新白鹿餐厅(运河上街店)',images:[$r('app.media.1_1'),$r('app.media.1_2')],area:'运河上街',address:'台州路运河上街购物中心F5',avgPrice:61,comments:8045,score:47,openHours:'10:39-21:00'}]// 给图片加上服务器地址前缀/*shops.forEach(s => {s.images.forEach((src,i) => {s.images[i] = 'http://localhost:3000' + src})})*/this.shops = shops}
}
// ShopItem.etsimport ShopInfo from '../viewmodel/ShopInfo'@Component
export default struct ShopItem {shop:ShopInfobuild() {Column({space:5}){Row(){Text(this.shop.name).fontSize(20).fontWeight(FontWeight.Bold).textOverflow({overflow: TextOverflow.Ellipsis})}.width('100%')Row(){Text(this.shop.address).fontColor('a3a3a3').textOverflow({overflow: TextOverflow.Ellipsis})}.width('100%')Row(){Text('★★★★★').fontColor(Color.Orange)Text((this.shop.score/10).toString()).fontColor(Color.Orange).margin({right:10})Text(`${this.shop.comments}`)Blank()Text(`¥${this.shop.avgPrice}/人`)}.width('100%')Row({space:10}){ForEach(this.shop.images,img =>{Image(img).width('50%').height(100)})}.width('100%')}.backgroundColor('#fff').borderRadius(10).padding(12)}
}
// ShopModel.tsimport http from '@ohos.net.http'
import ShopInfo from '../viewmodel/ShopInfo'class ShopModel{baseURL:string = 'localhost:3000'pageNo:number = 1getShopList(): Promise<ShopInfo[]>{return new Promise((resolve,reject) => {// 1、创建http的请求对象let httpRequest = http.createHttp()// 2、发送请求httpRequest.request(`${this.baseURL}/shops?pageNo=${this.pageNo}&pageSize=3`,{method:http.RequestMethod.GET}).then(resp => {if(resp.responseCode === 200){// 查询成功console.log('查询商铺成功!',resp.result)resolve(JSON.parse(resp.result.toString()))}else{console.log('查询商铺信息失败!error:',JSON.stringify(resp))reject('查询商铺失败')}}).catch(error => {console.log('查询商铺信息失败!error:',JSON.stringify(error))})})}
}const shopModel = new ShopModel
export default shopModel as ShopModel
// ShopInfo.tsexport default class ShopInfo {id:numbername:string// @ts-ignoreimages:Resource[]area:stringaddress:stringavgPrice:numbercomments:numberscore:numberopenHours:string
}

在这里插入图片描述

将 下载到的课程资料中相应项目中的 shopServer 文件夹整体复制到自己的项目中:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在浏览器中输入接口访问地址,测试服务器:

在这里插入图片描述

在这里插入图片描述

将获取数据的代码修改为调用接口从服务器获取:

在这里插入图片描述

// ShopPage.etsimport { Header } from '../components/CommonComponents'
import ShopInfo from '../viewmodel/ShopInfo'
import ShopItem from '../views/ShopItem'
import ShopModel from '../model/ShopModel'@Entry
@Component
struct ShopPage {@State shops: ShopInfo[] = []isLoading:boolean = falseisMore:boolean = trueaboutToAppear(){// 加载商品数据ShopModel.pageNo = 1this.loadShopInfo()}build() {Column({space:10}) {Header({title:'商铺列表'})List({space:10}){ForEach(this.shops, shop=>{ListItem(){ShopItem({shop:shop})}})}.padding({left:14,right:14}).layoutWeight(1).onReachEnd(()=>{console.log('触底了!')if(!this.isLoading && this.isMore){this.isLoading = trueShopModel.pageNo++this.loadShopInfo()}})}.width('100%').height('100%').backgroundColor('#efefef')}loadShopInfo(){// TODO 加载数据/*let shops = [{id:1,name:'新白鹿餐厅(运河上街店)',images:[$r('app.media.1_1'),$r('app.media.1_2')],area:'运河上街',address:'台州路运河上街购物中心F5',avgPrice:61,comments:8045,score:47,openHours:'10:39-21:00'},{id:2,name:'新白鹿餐厅(运河上街店)',images:[$r('app.media.1_1'),$r('app.media.1_2')],area:'运河上街',address:'台州路运河上街购物中心F5',avgPrice:61,comments:8045,score:47,openHours:'10:39-21:00'}]*/// 加载数据ShopModel.getShopList().then(shops => {// 给图片加上服务器地址前缀shops.forEach(s => {s.images.forEach((src,i) => {s.images[i] = 'http://localhost:3000' + src})})this.shops = this.shops.concat(shops)this.isLoading = falseif(!shops || shops.length === 0){this.isMore = false}})// 给图片加上服务器地址前缀/*shops.forEach(s => {s.images.forEach((src,i) => {s.images[i] = 'http://localhost:3000' + src})})*/// this.shops = shops}
}

版权声明:

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

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