onClick
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Entry @Component struct Index { @State textSize: number = 12 clickHandler() { this.textSize += 4 } build() { Column() { Text('onClick') .fontSize(this.textSize) .onClick(this.clickHandler.bind(this)) } } } |
@Builder
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
interface test { username: string } @Builder function MyBuilder($$: test) { Column() { Text($$.username) } } @Entry @Component struct Index { @State username: string = '张三' build() { Column() { Divider() MyBuilder({ username: this.username }) Button('click') .onClick(() => { this.username = '李四' }) } } } |
@State
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
class Person { public name: string public age: number constructor(name: string, age: number) { this.name = name this.age = age } } @Component struct MyChild { @State person: Person = new Person('张三', 12) private increaseBy: number = 1 build() { Column({ space: 10 }) { Text(this.person.name + ':' + this.person.age) Button('更改名字').onClick((event: ClickEvent) => { this.person.name = this.person.name == '张三' ? '李四' : '张三' }) Button('更改年龄').onClick((event: ClickEvent) => { this.person.age += this.increaseBy }) } } } @Entry @Component struct Index { build() { Column({ space: 20 }) { MyChild({ person: new Person('李四', 20) }) MyChild({ increaseBy: 2 }) } .width('100%') } } |
@Prop
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
@Component struct MyChild { @Prop age: number = 10 private increase: number = 1 build() { Column({ space: 10 }) { Text('子组件age:' + this.age) Button('修改age') .onClick(() => { this.age += this.increase }) } } } @Entry @Component struct Index { @State age: number = 10 build() { Column({ space: 20 }) { Text('父组件age:' + this.age) Button('修改父组件age').onClick((event: ClickEvent) => { this.age += 1 }) Divider() MyChild({ age: this.age, increase: 2 }) Divider() MyChild() } } } |
@Link
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
class ButtonState { public value: string public width: number constructor(value: string, width: number) { this.value = value this.width = width } } @Component struct MyChildGreenButton { @Link buttonState: ButtonState build() { Button(this.buttonState.value).onClick((event: ClickEvent) => { if (this.buttonState.width < 700) { this.buttonState.width += 100 } else { this.buttonState = new ButtonState('绿色按钮', 100) } }) .width(this.buttonState.width) .backgroundColor(Color.Green) } } @Component struct MyChildRedButton { @Link value: string @Link btnWidth: number build() { Button(this.value).onClick((event: ClickEvent) => { if (this.btnWidth < 700) { this.btnWidth += 100 } else { this.btnWidth = 100 } }) .width(this.btnWidth) .backgroundColor(Color.Red) } } @Entry @Component struct Index { @State parentGreenButton: ButtonState = new ButtonState('一号子组件', 200) @State parentRedValue: string = '二号子组件' @State parentRedWidth: number = 200 build() { Column({ space: 20 }) { Button(`父组件中修改绿色按钮宽度:${this.parentGreenButton.width}`) .onClick(() => { this.parentGreenButton.width = this.parentGreenButton.width < 700 ? this.parentGreenButton.width + 100 : 100 }) Button(`父组件中修改红色按钮宽度:${this.parentRedWidth}`) .onClick(() => { this.parentRedWidth = this.parentRedWidth < 700 ? this.parentRedWidth + 100 : 100 }) Divider() MyChildGreenButton({ buttonState: $parentGreenButton }) MyChildRedButton({ value: $parentRedValue, btnWidth: $parentRedWidth }) } } } |
if条件渲染
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
@Component struct MyChild { @Link counter: number @Prop label: string build() { Row({ space: 20 }) { Text(`${this.label}`) Button(`计数器的值:${this.counter}`) .onClick(() => { this.counter++ }) } } } @Entry @Component struct Index { @State flag: boolean = true @State counter: number = 0 build() { Column({ space: 20 }) { if (this.flag) { MyChild({ label: '真真', counter: $counter }) } else { MyChild({ label: '假假', counter: $counter }) } Divider() Button(`是否真假:${this.flag}`) .onClick(() => { this.flag = !this.flag }) } } } |
ForEach循环渲染
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
@Component struct MyChild { @Prop label: string build() { Text(this.label) } } @Entry @Component struct Index { @State myArray: string[] = ['one', 'two', 'three'] build() { Column() { ForEach(this.myArray, (item: string, index: number) => { MyChild({ label: item }) }) Button('点击修改第二个值') .onClick(() => { this.myArray[1] = 'new_two' }) } .justifyContent(FlexAlign.Center) .width('100%') .height('100%') } } |
List滑动加载
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
class Article { public id: number public title: string public content: string constructor(id: number, title: string, content: string) { this.id = id this.title = title this.content = content } } @Component struct ArticleComponent { @Prop article: Article build() { Row() { Image($r('app.media.app_icon')) .width(80) .height(80) .margin({ right: 20 }) Column({ space: 10 }) { Text(this.article.title) .fontSize(20) Text(this.article.content) .fontSize(16) .fontColor(Color.Gray) } .alignItems(HorizontalAlign.Start) .width('90%') .height('100%') } .padding(20) .borderRadius(12) .backgroundColor('#FFECECEC') .width('100%') .height(120) .justifyContent(FlexAlign.SpaceBetween) } } @Entry @Component struct Index { @State isListReachEnd: boolean = false @State articleArray: Article[] = [ new Article(1, '第一篇文章', '文章的内容和介绍'), new Article(2, '第二篇文章', '文章的内容和介绍'), new Article(3, '第三篇文章', '文章的内容和介绍'), new Article(4, '第四篇文章', '文章的内容和介绍'), new Article(5, '第五篇文章', '文章的内容和介绍'), new Article(6, '第六篇文章', '文章的内容和介绍'), ] build() { Column() { List() { ForEach(this.articleArray, (item: Article) => { ArticleComponent({ article: item }) .margin({ bottom: 20 }) }) }.onReachEnd(() => { this.isListReachEnd = true }) .parallelGesture(PanGesture({ direction: PanDirection.Up, distance: 80 }) .onActionStart(() => { if (this.isListReachEnd) { let count = this.articleArray.length let id = count + 1 this.articleArray.push(new Article(id, `第${id}篇文章`, '文章的内容和介绍')) this.isListReachEnd = false } })) .scrollBar(BarState.Off) } .padding(20) .width('100%') } } |
案例:待办列表
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
@Component struct ToDoItem { private content?: string @State isComplete: boolean = false @Builder labelIcon(icon: Resource) { Image(icon) .width(20) .margin({ right: 10 }) } build() { Row() { if (this.isComplete) { this.labelIcon($r('app.media.ic_ok')) } else { this.labelIcon($r('app.media.ic_default')) } Text(this.content) .width('90%') .opacity(this.isComplete ? 0.6 : 1) .decoration({ type: this.isComplete ? TextDecorationType.LineThrough : TextDecorationType.None }) } .width('100%') .height(50) .backgroundColor('#fff') .padding(10) .borderRadius(10) .onClick(() => { this.isComplete = !this.isComplete }) } } class DataModel { private tasks: string[] = [ '早起晨练', '准备早餐', '阅读名著', '学习ArkTS', '看剧放松' ] getData(): string[] { return this.tasks } } @Entry @Component struct Index { @State todoTasks: string[] = (new DataModel()).getData() @Builder pageTitle() { Text('待办') .fontSize(24) .width('100%') .margin({ top: 20, bottom: 20 }) .fontWeight(FontWeight.Bold) .textAlign(TextAlign.Start) } build() { Column({ space: 10 }) { this.pageTitle() ForEach(this.todoTasks, (content: string, index: number) => { ToDoItem({ content }) }) } .padding(20) .width('100%') .height('100%') .backgroundColor('#F1F3F5') } } |
案例:水果排行
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
import { common } from '@kit.AbilityKit' class FruitsData { id: number name: string vote: number constructor(id: number, name: string, vote: number) { this.id = id this.name = name this.vote = vote } } @Component struct TitleComponent { @Prop title: string @Link isSwitchDataSource: boolean build() { Row() { Row() { Image($r('app.media.back')) .width(20) .margin({ right: 15 }) .onClick(() => { let context = getContext(this) as common.UIAbilityContext context.terminateSelf() }) Text(this.title) } Image($r('app.media.loading')) .width(20) .onClick(() => { this.isSwitchDataSource = !this.isSwitchDataSource }) } .width('100%') .height(55) .padding({ left: 10, right: 10, top: 15, bottom: 15 }) .justifyContent(FlexAlign.SpaceBetween) } } @Component struct TableHeaderComponent { @Prop widthValue: Length build() { Row() { Text('排名') .fontColor(Color.Gray) .width('20%') Text('种类') .fontColor(Color.Gray) .width('50%') Text('得票数') .fontColor(Color.Gray) .width('30%') } .width(this.widthValue) .height(40) .padding(15) } } @Component struct ItemComponent { @Prop index: number @Prop name: string @Prop vote: number @State isChoice: boolean = false build() { Row() { if (this.index <= 3) { this.circleIndex() } else { Text(this.index.toString()) .width('20%') } Text(this.name) .width('50%') .fontColor(this.isChoice ? Color.Blue : Color.Black) Text(this.vote.toString()) .width('30%') .fontColor(this.isChoice ? Color.Blue : Color.Black) } .width('100%') .height(40) .onClick(() => { this.isChoice = !this.isChoice }) } @Builder circleIndex() { Row() { Row() { Text(this.index.toString()) .fontColor(Color.White) } .width(22) .height(22) .borderRadius(11) .backgroundColor('#5500FF') .justifyContent(FlexAlign.Center) .alignItems(VerticalAlign.Center) } .width('20%') } } @Entry @Component struct Index { @State dataSource1: FruitsData[] = [ new FruitsData(1, '苹果', 5432), new FruitsData(2, '西梅', 3676), new FruitsData(3, '无花果', 2254), new FruitsData(4, '水蜜桃', 2154), new FruitsData(5, '葡萄', 2023), new FruitsData(6, '圣女果', 1973), new FruitsData(7, '西瓜', 1817), new FruitsData(8, '香蕉', 1732), ] @State dataSource2: FruitsData[] = [ new FruitsData(9, '西梅', 6676), new FruitsData(10, '无花果', 6354), new FruitsData(11, '杨梅', 5853), new FruitsData(12, '西瓜', 4817), new FruitsData(13, '香蕉', 3732), new FruitsData(14, '榴莲', 2704), new FruitsData(15, '杨桃', 1636), new FruitsData(16, '梨', 1422), ] @State isSwitchDataSource: boolean = false @Builder createList() { Column() { List() { ForEach(this.isSwitchDataSource ? this.dataSource1 : this.dataSource2, (item: FruitsData, index: number) => { ItemComponent({ index: index + 1, name: item.name, vote: item.vote }) }) } .divider({ strokeWidth: 1 }) .height('65%') } .width('92%') .padding(15) .borderRadius(15) .backgroundColor(Color.White) } build() { Column() { TitleComponent({ title: '水果排行榜', isSwitchDataSource: this.isSwitchDataSource }) TableHeaderComponent({ widthValue: '92%' }) this.createList() } .width('100%') .height('100%') .backgroundColor('#F1F3F5') } } |
状态管理实践
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
@Observed class Translate { translateX: number = 20 } @Entry @Component struct Index { @State translateObj: Translate = new Translate() buttonMsg: string = 'I am button' build() { Column() { Text(this.translateObj.translateX.toString()) Button(this.buttonMsg) .onClick(() => { animateTo({ duration: 50 }, () => { this.translateObj.translateX = (this.translateObj.translateX + 50) % 150 }) }) } .translate({ x: this.translateObj.translateX }) } } |
@Watch
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
@Entry @Component struct UseWatchListener { @State currentIndex: number = 0; // 当前选中的列表项下标 private listData: string[] = []; aboutToAppear(): void { for (let i = 0; i < 10; i++) { this.listData.push(`组件 ${i}`); } } build() { Row() { Column() { List() { ForEach(this.listData, (item: string, index: number) => { ListItem() { ListItemComponent({ item: item, index: index, currentIndex: this.currentIndex }) } }) } .height('100%') .width('100%') .alignListItem(ListItemAlign.Center) } .width('100%') } .height('100%') } } @Component struct ListItemComponent { @Prop item: string; @Prop index: number; // 列表项的下标 @Link @Watch('onCurrentIndexUpdate') currentIndex: number; @State color: Color = Math.abs(this.index - this.currentIndex) <= 1 ? Color.Red : Color.Blue; isRender(): number { console.info(`ListItemComponent ${this.index} Text is rendered`); return 20; } onCurrentIndexUpdate() { // 根据当前列表项下标index与currentIndex的差值来动态修改color的值 this.color = Math.abs(this.index - this.currentIndex) <= 1 ? Color.Red : Color.Blue; } build() { Column() { Text(this.item) .fontSize(this.isRender()) .fontColor(this.color) .onClick(() => { this.currentIndex = this.index; }) } } } |
自定义事件发布订阅
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
import { emitter } from '@kit.BasicServicesKit'; @Entry @Component struct UseEmitterPublish { listData: string[] = ['A', 'B', 'C', 'D', 'E', 'F']; build() { Column() { Row() { Column() { ButtonComponent() } } Column() { Column() { List() { ForEach(this.listData, (item: string, index: number) => { ListItemComponent({ myItem: item, index: index }) }) } .height('100%') .width('100%') .alignListItem(ListItemAlign.Center) } } } } } @Component export struct ButtonComponent { value: number = 2; build() { Button(`下标是${this.value}的倍数的组件文字变为红色`) .onClick(() => { let event: emitter.InnerEvent = { eventId: 1, priority: emitter.EventPriority.LOW }; let eventData: emitter.EventData = { data: { value: this.value } }; // 发送eventId为1的事件,事件内容为eventData emitter.emit(event, eventData); this.value++; }) } } @Component export struct ListItemComponent { @State color: Color = Color.Black; @Prop index: number; @Prop myItem: string; aboutToAppear(): void { let event: emitter.InnerEvent = { eventId: 1 }; // 收到eventId为1的事件后执行该回调 let callback = (eventData: emitter.EventData): void => { if (eventData.data?.value !== 0 && this.index % eventData.data?.value === 0) { this.color = Color.Red; } }; // 订阅eventId为1的事件 emitter.on(event, callback); } build() { Column() { Text(this.myItem) .fontSize(50) .fontColor(this.color) } } } |