1. 涉及到的技术点
- axios的使用(在第四集中,教了如何使用axios获取影片数据)
- @Extend装饰器的使用
2. 官方文档指南
3.为什么要使用@Extend装饰器?
- 官方说明:如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,我们推出了可以提炼公共样式进行复用的装饰器@Styles,@Extend
- 在第六集中,细心的同学会发现在设置tabBar样式的时候,每个分类的样式重复了好多相同的代码,所以官方也考虑到了这个问题,建议使用装饰器来解决这个问题,看看下图没有利用装饰器写的代码
3. demo具体实现
- 定义@Extend装饰器
/**
* 1. 使用@Extend装饰器:定义扩展组件样式
* 2. 如何使用?
* 官网文档指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-extend-V5
*/
@Extend(TabContent)
function funcCategoryTextStyle(titleName: string) {
.tabBar(SubTabBarStyle.of(titleName).indicator({
color: '#e22418', //下划线颜色
borderRadius: 4, //下划线圆角半径
height: 3, //下划线高度
})
.labelStyle({
selectedColor: '#e22418', //选中时的颜色
unselectedColor: '#ff999999' //未选中时的颜
})
)
}
- 讲了这么多,看看使用了装饰器之后的代码简洁度吧
import axios, { AxiosError, AxiosResponse } from '@ohos/axios';
import { MovieInfo, MovieInfoItem } from '../entity/MovieInfo';
import { router } from '@kit.ArkUI';
/**
* 1. 使用@Extend装饰器:定义扩展组件样式
* 2. 如何使用?
* 官网文档指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-extend-V5
*/
@Extend(TabContent)
function funcCategoryTextStyle(titleName: string) {
.tabBar(SubTabBarStyle.of(titleName).indicator({
color: '#e22418', //下划线颜色
borderRadius: 4, //下划线圆角半径
height: 3, //下划线高度
})
.labelStyle({
selectedColor: '#e22418', //选中时的颜色
unselectedColor: '#ff999999' //未选中时的颜
})
)
}
@Entry
@Component
struct CategoryPage {
@State currentIndex: number = 0
@State movieInfo: MovieInfo = {
subjects: []
}
titles: string[] = ['最新', '华语', '欧美', '韩国', '日本', '中国香港', '中国台湾', '印度', '泰国', '其他']
aboutToAppear(): void {
this.getMovieListData(this.titles[0])
}
/**
* 获取最近热门电影
*/
getMovieListData(categoryName:string) {
axios<string, AxiosResponse<string>, null>({
method: "get",
params:{
'tag':categoryName
},
url: 'https://movie.douban.com/j/search_subjects?type=movie&page_limit=50&page_start=0'
}).then((res: AxiosResponse) => {
this.movieInfo = res.data
}).catch((error: AxiosError) => {
console.error(error.message);
})
}
build() {
Column() {
Row() {
Image($r('app.media.img_back')).width(26).onClick(()=>{router.back()})
//标题栏
Text('分类')
.fontSize(21)
.fontWeight(600)
}
.width('100%')
//tabs页面
Tabs() {
ForEach(this.titles, (title: string) => {
TabContent() {
//电影列表,网格布局
Grid() {
ForEach(this.movieInfo.subjects, (item: MovieInfoItem) => {
GridItem() {
Column() {
Image(item.cover)
.height(140)
.width('100%')
.objectFit(ImageFit.Cover)
Text(item.title)
.fontSize(13)
.margin({ top: 6 })
.textOverflow({
overflow: TextOverflow.Clip
})
.maxLines(1) //一般情况下textOverflow和maxLines配合一起使用
}.width('100%')
}.onClick(() => {
})
})
}
.columnsTemplate('1fr 1fr 1fr')
.margin({ top: 20 })
.columnsGap(10)
.rowsGap(10)
.margin(10)
}
.funcCategoryTextStyle(title)
})
/**
* 滚动导航栏可以用于顶部导航栏或者侧边导航栏的设置,
* 内容分类较多,屏幕宽度无法容纳所有分类页签的情况下
* ,需要使用可滚动的导航栏,支持用户点击和滑动来加载隐藏的页签内容。
* 滚动导航栏需要设置Tabs组件的barMode属性,
* 默认值为BarMode.Fixed表示为固定导航栏,
* BarMode.Scrollable表示可滚动导航栏
*/
}
.barMode(BarMode.Scrollable)
//设置点击TabBar页签时切换TabContent的动画形式
.animationMode(AnimationMode.NO_ANIMATION)
.onChange((index: number) => {
this.movieInfo.subjects =[]
this.getMovieListData(this.titles[index])
})
}
.height('100%')
.width('100%')
}
}
获取电影数据的方法,在生命周期aboutToAppear()函数中调用