当前位置:   article > 正文

鸿蒙HarmonyOS4.0 -(ArkTs)_鸿蒙 arktu实时刷新

鸿蒙 arktu实时刷新

基本语法

  • 装饰器:如下图@Entry、@Component、@State都是装饰器。
    • @Component表示自定义组件。
    • @Entry表示该自定义组件的入口组件。
    • @State表示组件中的状态变量,状态变量的变化会触发UI的刷新。
  • UI描述:以声明式的方式来描述UI的结构,如上图build()方法中的代码。
  • 自定义组件:可复用的UI组件,如上图被@Component装饰的struct App。
  • 属性方法:通过链式调用使用更多属性,如上图.width('100%').height('100%')等。
  • 事件方法:通过链式调用使用更多事件逻辑,如上图中的.onClick(()=>{ })等。

  1. @Entry
  2. @Component
  3. struct App {
  4. @State myText: string = 'HarmonyOS4.0';
  5. build() {
  6. Column() {
  7. Text(`${this.myText}`).fontSize(32).fontWeight(800)
  8. Button('点击').onClick(() => {
  9. this.myText = '欢迎使用鸿蒙'
  10. }).width(100).margin({top:20})
  11. }.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
  12. }
  13. }

创建自定义组件

注意:@Entry装饰的组件,其build函数下的根结点必须为容器组件,并且forEach不能作为根节点。     

           @Component装饰的组件,其build函数下的根结点可以为非容器组件,并且forEach不能作为根节点。            

1、在入口组件内部使用自定义组建
  1. @Component
  2. struct ExanpleComponent {
  3. @State textValue: string = '组件状态'
  4. build() {
  5. Text(this.textValue)
  6. .fontSize(32)
  7. .fontWeight(600)
  8. .fontColor('#e33')
  9. .onClick(() => {
  10. this.textValue = '组件状态变化'
  11. })
  12. }
  13. }
  14. @Entry
  15. @Component
  16. struct App {
  17. @State myText: string = 'HarmonyOS4.0';
  18. build() {
  19. Column() {
  20. ExanpleComponent()
  21. Text(`${this.myText}`)
  22. .fontSize(32)
  23. .fontWeight(800)
  24. Button('点击')
  25. .width(100)
  26. .margin({ top: 20 })
  27. .onClick(() => {
  28. this.myText = '欢迎使用鸿蒙'
  29. })
  30. }.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
  31. }
  32. }
2、从外部导入使用自定义组建

Index.ets @Entry入口文件

Example.ets @Component自定义组件文件

生命周期(页面和自定义组件)

1、页面生命周期,即被@Entry修饰的组件生命周期
  • onPageShow:页面每次显示时触发。
  • onPageHide:页面每次隐藏时触发。
  • onBackPress:当用户点击返回按钮时出发。
2、组件生命周期,即被@Component修饰的组件生命周期
  • aboutToAppear:组件刚出现的时候回调该接口,具体为在创建自定义组件实例后早build函数前。
  • aboutToDisappear:在自定义组件销毁时执行。

@Styles

注意:@Style不能有参数。

  1. // 定义全局@style样式
  2. @Styles function publicStyle() {
  3. .width('100%')
  4. .height('100%')
  5. .backgroundColor('#3ce')
  6. }
  7. @Entry
  8. @Component
  9. struct App {
  10. @State myText: string = 'HarmonyOS4.0';
  11. // 定义局部@style样式
  12. @Styles internalStyle(){
  13. .width(200)
  14. .margin({ top: 20 })
  15. }
  16. build() {
  17. Column() {
  18. Button(this.myText)
  19. .internalStyle()
  20. .fontSize(20)
  21. .onClick(() => {
  22. this.myText = '欢迎使用鸿蒙'
  23. })
  24. }.publicStyle().justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
  25. }
  26. }

@Extend

概念

  • 和@Style不同,@Extend仅支持定义在全局,不支持在组件内部定义。
  • 和@Style不同,@Extend装饰的方法支持参数,可以在调用时传递参数
  1. // 定义全局@Extend样式
  2. @Extend(Column) function publicStyle(width:string,height:string) {
  3. .width(width)
  4. .height(height)
  5. .backgroundColor('#3ae')
  6. }
  7. @Entry
  8. @Component
  9. struct App {
  10. @State myText: string = 'HarmonyOS4.0';
  11. build() {
  12. Column() {
  13. Button(this.myText)
  14. .fontSize(20)
  15. .onClick(() => {
  16. this.myText = '欢迎使用鸿蒙'
  17. })
  18. }.publicStyle('100%','100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
  19. }
  20. }

stateStyles多态样式

概述

stateStyles是属性方法,类似于css伪类,ArkUI提供了以下四种状态:

  • focused:获焦状态
  • normal:正常状态
  • pressed:按压状态
  • disabled:不可用状态
  1. @Styles function focusedStyle() {
  2. .backgroundColor('red')
  3. }
  4. @Entry
  5. @Component
  6. struct App {
  7. @State myText: string = 'HarmonyOS4.0';
  8. @Styles pressedStyle() {
  9. .backgroundColor('green')
  10. }
  11. build() {
  12. Column() {
  13. Button(this.myText)
  14. .fontSize(20)
  15. .stateStyles({
  16. focused: focusedStyle,
  17. pressed: this.pressedStyle,
  18. normal: {
  19. .backgroundColor('blue')
  20. },
  21. })
  22. .onClick(() => {
  23. this.myText = '欢迎使用鸿蒙'
  24. })
  25. }.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
  26. }
  27. }

@State状态管理

概念

  • 状态变量:被@State装饰的变量,状态变量的状态值的改变会引起UI的渲染更新。
  • 常规变量:没有被@State装饰的变量,它的改变永远不会引起UI的渲染更新。
  1. @Component
  2. struct MyComponent {
  3. @State count: number = 0;
  4. private increaseBy: number = 1;
  5. build() {
  6. }
  7. }
  8. @Component
  9. struct Parent {
  10. build() {
  11. Column() {
  12. // 从父组件初始化,覆盖本地定义的默认值
  13. MyComponent({ count: 1, increaseBy: 2 })
  14. }
  15. }
  16. }

@Prop父子单项同步(父传子)

概述

  • 单项同步:对父组件的状态变量值的修改,将同步到子元素@Prop装饰的变量,子组件@Prop变量的修改不会同步到父组件的状态变量上。

注意:@props装饰器不能在@Entry装饰的自定义组件中使用。

  1. @Component
  2. struct Child {
  3. @Prop count: number;
  4. build() {
  5. Column() {
  6. Text(`子组件: ${this.count} `)
  7. // @Prop装饰的变量不会同步给父组件
  8. Button(`子组件-1`).onClick(() => {
  9. this.count -= 1;
  10. }).margin({ top: 24 })
  11. }
  12. }
  13. }
  14. @Entry
  15. @Component
  16. struct Parent {
  17. @State num: number = 0;
  18. build() {
  19. Column() {
  20. Text(`父组件:${this.num}`)
  21. // 父组件的修改会同步给子组件
  22. Button(`父组件+1`).onClick(() => {
  23. this.num += 1;
  24. }).margin({ top: 24 })
  25. // 子组件
  26. Child({ count: this.num }).margin({ top: 24 })
  27. }.width('100%').justifyContent(FlexAlign.Center).margin({ top: 24 })
  28. }
  29. }

@Link父子双向同步(父传子、子传父)

概述

  • 双向同步:对父组件的状态变量值的修改,将同步到子元素@Link装饰的变量,子组件@Link变量也将同步到父组件的状态变量上。

注意:@Link装饰器不能在@Entry装饰的自定义组件中使用。

  1. @Component
  2. struct Child {
  3. @Link items: number[];
  4. build() {
  5. Column() {
  6. Button(`子元素修改数组`).onClick(() => {
  7. this.items = [100, 200, 300];
  8. })
  9. ForEach(this.items, item => {
  10. Text(`${item}`)
  11. })
  12. }
  13. }
  14. }
  15. @Entry
  16. @Component
  17. struct Parent {
  18. @State arr: number[] = [1, 2, 3];
  19. build() {
  20. Column() {
  21. Button(`父元素修改数组`).onClick(() => {
  22. this.arr = [5, 6, 7];
  23. })
  24. ForEach(this.arr,
  25. item => {
  26. Text(`${item}`)
  27. }
  28. )
  29. Child({ items: $arr })
  30. }
  31. }
  32. }

@Provide和@Consume后代组件双向同步(跨组建传参)

概述

  • 双向同步:@Provide与@Consume,应用于后代组件的数据双向同步,应用于数据在多个层级之间传递,实现跨层级传递。
  • 介绍:@Provide装饰的变量是在祖先节点中,是变量的提供者,@Consume装饰的变量是在后代组件中,是变量的消费者。

注意:@Provide与@Consume装饰的变量必须通过相同的属性名进行同步数据。

  1. @Component
  2. struct CompD {
  3. // @Consume装饰的变量通过相同的属性名绑定其祖先组件CompA内的@Provide装饰的变量
  4. @Consume publicValue: number;
  5. build() {
  6. Column() {
  7. Text(`D组件${this.publicValue}`)
  8. Button(`D组件按钮-1`)
  9. .onClick(() => this.publicValue -= 1)
  10. }
  11. .width('50%')
  12. }
  13. }
  14. @Component
  15. struct CompC {
  16. build() {
  17. CompD()
  18. }
  19. }
  20. @Component
  21. struct CompB {
  22. build() {
  23. CompC()
  24. }
  25. }
  26. @Entry
  27. @Component
  28. struct CompA {
  29. // @Provide装饰的变量publicValue由入口组件CompA提供其后代组件
  30. @Provide publicValue: number = 0;
  31. build() {
  32. Column() {
  33. Text(`A组件${this.publicValue}`)
  34. Button(`A组件按钮+1`)
  35. .onClick(() => this.publicValue += 1)
  36. CompB()
  37. }
  38. }
  39. }

@Observed和@ObjectLink多层嵌套双向同步

概述

  • 上文所述的装饰器只能观察到一层的变化,对于多层嵌套的情况,比如二维数组、多维对象,它们其他层级的变化是无法被观察的,因此引出了@Observed和@ObjectLink装饰器。

注意:

  • @ObjectLink装饰器不能在@Entry装饰的自定义组件中使用。
  • @ObjectLink装饰的变量不能被赋值。
// 开发进行中...

@Watch监听状态的变化

概述

  • LocalStorage是页面级的UI存储,通过@Entry装饰器接收的参数可以在页面内共享一个LocalStorage实例。
  1. @Entry
  2. @Component
  3. struct CompA {
  4. @Watch('change') @State count: number = 1
  5. change() {
  6. console.log(`状态变化${this.count}`)
  7. }
  8. build() {
  9. Column() {
  10. Button(`点击状态变化${this.count}`)
  11. .onClick(() => {
  12. this.count++
  13. })
  14. }
  15. }
  16. }

LocalStorage页面级UI状态存储

概述

  • LocalStorage是页面级的UI存储,通过@Entry装饰器接收的参数可以在页面内共享一个LocalStorage实例。
  • 被@Entry装饰的@Component,可以被分配一个LocalStorage实例,此组件的所有子组件都将获取对该LocalStorage实例的访问权限,一个LocalStorage实例在组建数上可以分配给多个组件。
  • 被@Component装饰的组件最多可访问一个LocalStorage实例和AppStorage。
  • LocalStorage根据与@Component装饰的组件的同步类型不同,提供了两个装饰器:
    •  @LocalStorageProp:@LocalStorageProp装饰的变量与LocalStorage中给予属性建立的是单向同步关系。
    •  @LocalStorageLink:@LocalStorageLink装饰的变量与LocalStorage中给予属性建立的是双向向同步关系。

注意:LocalStorage创建后,命名属性的类型不可更改

1、@LocalStorageProp —— 单项数据同步

  1. // import { Child } from '../components/Example'
  2. let storage = new LocalStorage({ 'PropA': 47 });
  3. @Component
  4. struct Child {
  5. @LocalStorageProp('PropA') num2: number = 1;
  6. build() {
  7. // 点击后,只改变当前组件显示的num2,不会同步到LocalStorage中
  8. Button(`子组件${this.num2}`)
  9. .onClick(() => {
  10. this.num2 += 1;
  11. })
  12. }
  13. }
  14. @Entry(storage)
  15. @Component
  16. struct CompA {
  17. @LocalStorageProp('PropA') num1: number = 1;
  18. build() {
  19. Column({ space: 15 }) {
  20. Child()
  21. // 点击后,只改变当前组件显示的num1,不会同步到LocalStorage中
  22. Button(`父组件 ${this.num1}`)
  23. .onClick(() => this.num1 += 1)
  24. }
  25. }
  26. }

2、@LocalStorageLink  —— 双项数据同步

  1. // import { Child } from '../components/Example'
  2. let storage = new LocalStorage({ 'PropA': 47 });
  3. @Component
  4. struct Child {
  5. @LocalStorageLink('PropA') num2: number = 1;
  6. build() {
  7. Button(`子组件${this.num2}`)
  8. .onClick(() => {
  9. this.num2 += 1;
  10. })
  11. }
  12. }
  13. @Entry(storage)
  14. @Component
  15. struct CompA {
  16. @LocalStorageLink('PropA') num1: number = 1;
  17. build() {
  18. Column({ space: 15 }) {
  19. Child()
  20. Button(`父组件 ${this.num1}`)
  21. .onClick(() => this.num1 += 1)
  22. }
  23. }
  24. }

AppStorage全局UI状态存储

概述

  • AppStorage是应用全局的状态存储,和LocalStorage不同的是LocalStorage是页面级的,用于页面内的数据共享,而AppStorage是应用于全局状态的共享。
  • AppStorage中也提供了两种同步类型:
    • @StorageProp:@StorageProp(key)是和AppStorage中key对应的属性建立单向数据同步。
    • @StorageLink:@StorageLink(key)是和AppStorage中key对应的属性建立双向数据同步。

1、@StorageProp —— 单项数据同步

  1. AppStorage.SetOrCreate('PropA', 47);
  2. @Component
  3. struct Child {
  4. @StorageProp('PropA') num2: number = 1;
  5. build() {
  6. Button(`子组件${this.num2}`)
  7. .onClick(() => {
  8. this.num2 += 1;
  9. })
  10. }
  11. }
  12. @Entry()
  13. @Component
  14. struct CompA {
  15. @StorageProp('PropA') num1: number = 1;
  16. build() {
  17. Column({ space: 20 }) {
  18. Child()
  19. Button(`AppStorage ${this.num1}`)
  20. .onClick(() => this.num1 += 1)
  21. }
  22. }
  23. }

2、@StorageLink  —— 双项数据同步

  1. AppStorage.SetOrCreate('PropA', 47);
  2. @Entry()
  3. @Component
  4. struct CompA {
  5. @StorageLink('PropA') storLink: number = 1;
  6. build() {
  7. Column({ space: 20 }) {
  8. Button(`AppStorage ${this.storLink}`)
  9. .onClick(() => this.storLink += 1)
  10. }
  11. }
  12. }

总结:LocalStorage和AppStorage都是运行时内存的状态存储。

PersistentStorage持久化UI状态存储

概述

  • LocalStorage和AppStorage都是运行时的内存,在应用退出再次启动后,依然能保存选定的结果,这就需要用到PersistentStorage。
  • PersistentStorage将选定的AppStorage属性保留在设备磁盘上。
  1. PersistentStorage.PersistProp('aProp', 47);
  2. @Entry
  3. @Component
  4. struct Index {
  5. @StorageLink('aProp') num: number = 48
  6. build() {
  7. Row() {
  8. Column() {
  9. // 应用退出时会保存当前结果。重新启动后,会显示上一次的保存结果
  10. Button(`${this.num}`)
  11. .onClick(() => {
  12. this.num += 1;
  13. })
  14. }
  15. }
  16. }
  17. }

if/else

概述

  • 条件渲染使用if/else渲染对应状态下的ui内容。
  • 鸿蒙开发推荐使用if/else,不推荐使用switch。

ForEach

概述

  • 循环渲染,需要与容器组件配合使用。
  1. @Entry
  2. @Component
  3. struct Parent {
  4. @State simpleList: Array<string> = ['one', 'two', 'three'];
  5. build() {
  6. Row() {
  7. Column() {
  8. ForEach(this.simpleList, // 数据源
  9. (item: string) => {
  10. Text(item).fontSize(32) // 组件生成函数
  11. },
  12. (item: string) => item // 键值生成函数:为数据源arr的每个数组项生成唯一且持久的键值。
  13. )
  14. }
  15. }
  16. }
  17. }

LazyForEach

概述

  • LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。
  • LazyForEach必须在容器组件内使用,目前仅有List、Grid以及Swiper组件支持数据懒加载,其他组件仍然是一次性加载所有的数据。
  • LazyForEach在每次迭代中,必须创建且只允许创建一个子组件。
  1. class BasicDataSource implements IDataSource {
  2. private listeners: DataChangeListener[] = []
  3. public totalCount(): number {
  4. return 0
  5. }
  6. public getData(index: number): any {
  7. return undefined
  8. }
  9. registerDataChangeListener(listener: DataChangeListener): void {
  10. if (this.listeners.indexOf(listener) < 0) {
  11. console.info('add listener')
  12. this.listeners.push(listener)
  13. }
  14. }
  15. unregisterDataChangeListener(listener: DataChangeListener): void {
  16. const pos = this.listeners.indexOf(listener);
  17. if (pos >= 0) {
  18. console.info('remove listener')
  19. this.listeners.splice(pos, 1)
  20. }
  21. }
  22. notifyDataReload(): void {
  23. this.listeners.forEach(listener => {
  24. listener.onDataReloaded()
  25. })
  26. }
  27. notifyDataAdd(index: number): void {
  28. this.listeners.forEach(listener => {
  29. listener.onDataAdd(index)
  30. })
  31. }
  32. notifyDataChange(index: number): void {
  33. this.listeners.forEach(listener => {
  34. listener.onDataChange(index)
  35. })
  36. }
  37. notifyDataDelete(index: number): void {
  38. this.listeners.forEach(listener => {
  39. listener.onDataDelete(index)
  40. })
  41. }
  42. notifyDataMove(from: number, to: number): void {
  43. this.listeners.forEach(listener => {
  44. listener.onDataMove(from, to)
  45. })
  46. }
  47. }
  48. class MyDataSource extends BasicDataSource {
  49. // 初始化数据列表
  50. private dataArray: string[] = ['demo1', 'demo2', 'demo3', 'demo4']
  51. public totalCount(): number {
  52. return this.dataArray.length
  53. }
  54. public getData(index: number): any {
  55. return this.dataArray[index]
  56. }
  57. public addData(index: number, data: string): void {
  58. this.dataArray.splice(index, 0, data)
  59. this.notifyDataAdd(index)
  60. }
  61. public pushData(data: string): void {
  62. this.dataArray.push(data)
  63. this.notifyDataAdd(this.dataArray.length - 1)
  64. }
  65. }
  66. @Entry
  67. @Component
  68. struct MyComponent {
  69. private data: MyDataSource = new MyDataSource()
  70. build() {
  71. List({ space: 3 }) {
  72. LazyForEach(this.data, (item: string) => {
  73. ListItem() {
  74. Row() {
  75. Text(item).fontSize(20).margin({ left: 10 })
  76. }.margin({ left: 10, right: 10 })
  77. }
  78. .onClick(() => {
  79. // 每点击一次列表项,数据增加一项
  80. this.data.pushData(`demoVale:${this.data.totalCount()}`)
  81. })
  82. }, item => item)
  83. }.backgroundColor('red')
  84. }
  85. }

应用/组件配置

概述

  • 应用图标、应用标签和入口图标、入口标签的配置,分别对应app.json5配置文件module.json5配置文件文件中的icon和label标签。
  • 应用图标和标签是在设置应用中使用,例如设置应用中的应用列表。
  • 入口图标是应用安装完成后在设备桌面上中使用。

1、应用配置

2、入口配置

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/337242
推荐阅读
相关标签
  

闽ICP备14008679号