- 作者:老汪软件技巧
- 发表时间:2024-08-29 07:02
- 浏览量:
第三篇:接入第三方库,使用Axios网络请求,PullToRefresh上拉刷新下拉加载
第一篇:创建一个应用,使用Tabs和导航栏结构
第二篇:使用网格Grid与列表list
第三篇:接入第三方库,使用Axios网络请求,PullToRefresh上拉刷新下拉加载
第四篇:整理工程 - 模块化 (敬请期待)
背景:鸿蒙0基础探索。
愿景:本系列旨在用简单直接的方式从让鸿蒙app先从0-1。
理由:有产出更有继续下去的动力。
记录:每篇文章保留下探索的过程。
PS: 不教写代码,不封装,业务代码能力因人而异。(关键我不会啊)
书接上回。我们现在学会了使用Tabs,Navigation,Grid。有了这几件的基础,自然就可以探索网络请求,和模型解析。(这一篇探索完是不是感觉写个小应用没啥问题了。)
探索
说到网络请求,介于iOS经验,第一步我想到的就是使用网络请求的第三方库。(毕竟在项目中,真的很少用自带的直接进行请求)。顺便也尝试一下怎么集成第三方库。
通过搜索鸿蒙第三方库就会找到,
怎么安装包文档
一进来我们就发现了想要的,说明这个探索的路子是没错的。。额外补充一句这个ohos打头的不知道是不是官方维护的,因为看到还有别的知名库。比如lottie。那就愉快的决定使用ohos/axios了。
没有后台支持,接下来我要去找一个免费的API的接口。经过一番搜索。找到了github上免费api集合我挑了其中一个Animals - Cats的。Cats文档, ,填邮箱,会把apikey发送到邮箱。
ps:自己有后台,有其他接口用就不用这么麻烦了。我这就做了示例。
导入Axios,进行网络请求。
axios码云文档 :这个看起来更舒服。
怎么安装包文档中提到了几种安装方式。 我们结合着Axios的文档,选择用终端区安装,如下图所示,导入第三方是不是很简单。
文档上: 需要权限 ohos.permission.INTERNET, 不知道怎么做,老样子,我们先去官方文档上搜索一下,把前几个链接都点开扫一眼,找找关键词。我找到了这个。
于是乎我们也在module.json5中,添加这个配置。记得点Sync Now.
发起请求
发起一个 GET 请求
axios支持泛型参数,由于ArkTS不再支持any类型,需指定参数的具体类型。 如:axios.get(url)
我们现在对这样一个Api发起请求/v1/images/s…ps:返回的列表里图片怎么我用wifi不行,你也不行换几个网络环境试试。
我们不先定义模型,直接去发送请求(也不做任何额外的定义,先看能不能调通才是第一要素),通过log看看输出。
@Entry
@Component
export struct CatSqualPage {
// 页面出现的时候
aboutToAppear(): void {
// 去发送请求,
axios.get("https://api.thecatapi.com/v1/images/search", {params: { limit: "10"} })
.then((response: AxiosResponse) => {
console.warn("请求:" + JSON.stringify(response.config));
console.warn("请求结果result:" + JSON.stringify(response.data));
console.warn("请求结果类型result:" + typeof response.data );
// 便利打印
response.data.forEach(cat => {
console.warn(`ID: ${cat.id}, URL: ${cat.url}, Width: ${cat.width}, Height: ${cat.height}`);
});
})
.catch((error: AxiosError) => {
console.error("result:" + error.message);
});
}
build() {
}
}
能调通
模型解析
那接着我们看看接口返回的数据,想着给他做模型化。不得不说这库对解析的集成,真挺好用。比起iOS来说。
ps: 据说之前版本支持any,接口不需要做模型化也能用。现在Arkts禁用了any。
[
{
"id": "140",
"url": "https://cdn2.thecatapi.com/images/140.gif",
"width": 293,
"height": 163
}
]
结合上两篇我们所学的,用到NavDestination做导航子组件,Grid网格承接模型数据。网络请求成功后,刷新网格的数据,因此涉及到了数据绑定@State.
T,R应该都是泛型的意思。只需要声明一下,response.data就可以直接拿来用,真是方便呢。比如示例中:
axios.get, null>(参数1, 参数2)
示例代码:
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from '@ohos/axios'
@Builder
export function CatSqualPageBuilder() {
CatSqualPage()
}
// 自己创建一个示例,也可以用axios直接调用,我是为了练习,看看能配置些什么。
const gxwAxios = axios.create({
baseURL: 'https://api.thecatapi.com',
timeout: 3000,
})
// 实体类(猫的模型)
interface catInfo {
id: string,
url: string,
width: number,
height: number
}
@Entry
@Component
export struct CatSqualPage {
// 数据源
@State modelArray: catInfo[] = []
// 页面出现的时候
aboutToAppear(): void {
// 请求猫的数据
let config: AxiosRequestConfig = {
method: 'get',
params: {
limit : "10",
// 这两行注释打开就是另一个接口数据咯
//breed_ids: "beng",
//api_key: "live_uRCza6dSXUkli9FSLkPYL24UePJN2b9AD4D7hcanPKTfgV0v3jgS9hkCMd1Dp0bq"
}
}
//
gxwAxios.getAxiosResponse>("/v1/images/search", config)
.then((response: AxiosResponse ) => {
console.warn("请求:" + JSON.stringify(response.config));
console.warn("请求结果result:" + JSON.stringify(response.data));
console.warn("请求结果类型result:" + typeof response.data );
this.modelArray = response.data
// 便利打印
this.modelArray.forEach(cat => {
console.warn(`ID: ${cat.id}, URL: ${cat.url}, Width: ${cat.width}, Height: ${cat.height}`);
});
})
.catch((error: AxiosError) => {
console.error("result:" + error.message);
});
}
build() {
NavDestination() {
Column() {
Grid() {
ForEach(this.modelArray, (item: catInfo, index) => {
GridItem() {
Column() {
Image(item.url)
// 设置占位图。
.alt($rawfile('草/c1.png'))
}
}
.height('30%')
})
}
.columnsTemplate('1fr 1fr')
.rowsGap(10)
.columnsGap(20)
.backgroundColor(Color.Yellow)
}
.backgroundColor(Color.Red)
}
}
}
占位图
经过对文档的一番搜索只在api参考里发现,奇怪的是在指南中为什么没有提这个。通过观察ImageSpan是通过.alt属性设置占位图的,我就试了试Image有没有这个属性,发现是有的。
Image(item.url)
// 占位图
.alt($rawfile('火/h1.png'))
上拉加载下拉刷新
接口请求之后,自然就联想到了分页,刷新和加载更多的操作。
遇事不决就搜索搜索刷新关键词其结果都为我们指向了,正巧还能让我再次练习使用第三方库。
PullToRefresh代码文档
网络请求,网格,下拉刷新上拉加载代码都加上会有些凌乱,我们稍微调整一下。
比如:把网络请求写成一个function
ps: 我不会写Pormise或其他,只能模仿着iOS的Block来写。
// MARK: 请求数据
// 请求猫的数据,支持分页的数据。
requestCatsData(page: number, complete: (array: catInfo[]) => void, failure?: (error: AxiosError) => void ) {
// 参数
let config: AxiosRequestConfig = {
method: 'get',
params: {
page: page,
limit : "10",
// 这两行注释打开就是另一个接口数据咯
breed_ids: "beng",
api_key: "live_uRCza6dSXUkli9FSLkPYL24UePJN2b9AD4D7hcanPKTfgV0v3jgS9hkCMd1Dp0bq"
}
}
// 发送请求
gxwAxios.getAxiosResponse>("/v1/images/search", config)
.then((response: AxiosResponse ) => {
console.warn("请求:" + JSON.stringify(response.config));
console.warn("请求结果result:" + JSON.stringify(response.data));
console.warn("请求结果类型result:" + typeof response.data );
let result = response.data
// 便利打印
result.forEach(cat => {
console.warn(`ID: ${cat.id}, URL: ${cat.url}, Width: ${cat.width}, Height: ${cat.height}`);
});
complete(result)
})
.catch((error: AxiosError) => {
if (failure) {
failure(error)
}
});
}
把网格做成一个@Builder, 这有点像iOS中用一个UIView把控件包装一层注意这个Grid(this.scroller) .edgeEffect(EdgeEffect.None)这两行,我看了文档介入之后上下都拉不动,把PullToRefresh的demo下载下来一点点比才发现是这里。
// 网格
@Builder
creatMyGrid() {
Grid(**this.scroller**) {
ForEach(this.modelArray, (item: catInfo, index) => {
GridItem() {
Column() {
Image(item.url)
// 设置占位图。
.alt($rawfile('草/c1.png'))
}
}
.height('30%')
})
}
.columnsTemplate('1fr 1fr')
.rowsGap(10)
.columnsGap(20)
.width('100%')
.height('100%')
.edgeEffect(EdgeEffect.None)
.backgroundColor(Color.Yellow)
}