HarmonyOS 应用开发 —— 常用装饰器整理
当前版本:API9 纯
ArcTS
语言和Stage模式
学习 HarmonyOS 时,我们会用到各种各样的装饰器。
我们使用 DevEco IDLE 进行 HarmonyOS 应用开发时,在任意 .ets
文件中,输入 @
时,会弹出所有的装饰器,但是什么时候该用什么装饰器就需要查文档。但是官方文档没有搜到和装饰器
强相关的文档。
故自行总结常用装饰器的学习笔记
PS:由于楼主也在学习的过程中,所以可能有些地方写的不是很清晰,欢迎大家来指正
一、修饰 struct 或 class
@Entry
作用:表示自定义组件入口,一个组件有且只能拥有一个入口,及入口组件
案例:我们默认创建的项目,默认生成的文件就包含了 @Entry
代码语言:javascript复制@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
@Conponent
作用:表示当前 struct 是一个组件,可以单独使用,封装抽离文件
案例:使用方式如下,如果需要让别的组件使用该自定义组件,使用 import/export
语法 导出以及导入即可
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
}
@Preview
作用:Dev Eco 预览器提供的一个快捷注解,可以快速预览单个页面,以及组件
使用:
代码语言:javascript复制@Preview
@Entry // 使用了 @Preview 组件,@Entry 注解就不再是必要的了
@Component
struct TaskPage {
// ....
}
@Observed
作用:新闻发布案例中 NewsViewModel 会用到,会与变量修饰器 @ObjectLink
一起使用,可以挂多个组件建立连接
使用:
代码语言:javascript复制@Observed
export class CustomRefreshLoadLayoutClass {
/**
* Custom refresh load layout isVisible.
*/
isVisible: boolean;
/**
* Custom refresh load layout imageSrc.
*/
imageSrc: Resource;
/**
* Custom refresh load layout textValue.
*/
textValue: Resource;
/**
* Custom refresh load layout heightValue.
*/
heightValue: number;
constructor(isVisible: boolean, imageSrc: Resource, textValue: Resource, heightValue: number) {
this.isVisible = isVisible;
this.imageSrc = imageSrc;
this.textValue = textValue;
this.heightValue = heightValue;
}
}
二、修饰变量
@State
作用:用于组件内状态管理,使用该装饰器修饰的变量,当变量值发生改变后,会触发 ArkUI 的更新
案例:
代码语言:javascript复制@Component
struct Index {
@State message: string = 'Hello World'
build() {
Column() {
Text(this.message) // 在 HarmonOS 中并没有抛弃 this 的概念!
// ..
}
// ..
}
}
@Prop
作用:父组件 -> 子组件,单向同步状态
TODO:实际开发中暂时未遇到,如遇到了,在更新
@Link
父子组件双向同步状态
使用:
父组件
代码语言:javascript复制// ...
@Preview
@Component
export default struct TabBar {
@State tabBarArray: NewsTypeBean[] = NewsViewModel.getDefaultTypeList();
@State currentIndex: number = 0; // 定义 State 状态变量
@State currentPage: number = 1;
// ....
build() {
Tabs() {
ForEach(this.tabBarArray, (tabItems: NewsTypeBean) => {
TabContent() {
Column() {
NewsList({ currentIndex: $currentIndex }) // 这里传递的是引用
}
}
.tabBar(this.TabBuilder(tabItems.id))
}, (item: NewsTypeBean) => JSON.stringify(item))
}
// ...
.vertical(false)
}
}
子组件
代码语言:javascript复制export default struct NewsList {
@State newsModel: NewsModel = new NewsModel();
@Watch('changeCategory') @Link currentIndex: number;
// 定义监听函数
changeCategory() {
this.newsModel.currentPage = 1;
NewsViewModel.getNewsList(this.newsModel.currentPage, this.newsModel.pageSize, Const.GET_NEWS_LIST)
.then((data: NewsData[]) => {
this.newsModel.pageState = PageState.Success;
if (data.length === this.newsModel.pageSize) {
this.newsModel.currentPage ;
this.newsModel.hasMore = true;
} else {
this.newsModel.hasMore = false;
}
this.newsModel.newsData = data;
})
.catch((err: string | Resource) => {
promptAction.showToast({
message: err,
duration: Const.ANIMATION_DURATION
});
this.newsModel.pageState = PageState.Fail;
});
}
aboutToAppear() {
// Request news data
this.changeCategory();
}
// ..
}
@Watch
和 @Link 一起使用,监听状态变化
使用:见上一个案例
@Provide [待更新]
作用:跨组件通信,可以给祖父组件的变量修饰
@Consume [待更新]
作用:跨组件通信,可以给孙子组件的变量修饰
@ObjectLink [待更新]
与被 @Observed 修饰过的 class 结合一起使用,具体作用待了解
TODO: 暂时还未摸清楚具体作用,也没有合适的案例,暂时先不提供了
三、修饰函数
使用修饰函数的装饰器,我们可以进一步抽离繁杂冗余的样式,可复用的代码逻辑,降低代码的复杂程度
@Builder
作用:用来修饰一个函数,快速生成布局内容,从而避免编写重复的样式,可以直接封装一个可复用 并且附带样式 的组件
案例:
代码语言:javascript复制@Component
export default struct TodoItem {
@State isComplete: boolean = false;
@Builder labelIcon(url) {
Image(url)
.objectFit(ImageFit.Contain)
.width(24)
.height(24)
.margin({
right: 15,
top: 5
})
}
build() {
Row() {
if (this.isComplete) {
this.labelIcon($r("app.media.select"))
} else {
this.labelIcon($r("app.media.unselect"))
}
// ..
}
}
}
@Style
作用:用来修饰一个函数,保存样式,可以直接提供给组件使用
语法:
代码语言:javascript复制// 统一卡片样式
@Styles function card() {
.width('95%')
.padding(20)
.backgroundColor(0xffffff)
.borderRadius(15)
.shadow({ radius: 6, color: 0x1F000000, offsetX: 2, offsetY: 4})
}
@Extend
作用:继承一个内置组件,并且开发者可扩展出其他常用属性
语法:
代码语言:javascript复制@Extend(Text) function finishedTask() {
.decoration({ type: TextDecorationType.LineThrough })
.fontColor(0xB1B2B1)
}
案例:
代码语言:javascript复制 // ...
Row() {
Text(item.name)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.finishedTask()
}
// ...
// 这里需要定在 struct 文件之外
@Extend(Text) function finishedTask() {
.decoration({ type: TextDecorationType.LineThrough })
.fontColor(0xB1B2B1)
}