Wsh's blog Wsh's blog
首页
  • Agent基础
  • Agent设计模式
  • 基础知识
  • ArkUI
  • UIAbility
  • 组件通信方式
  • 前端缓存
  • React
  • typescript
  • javascript
  • flutter
  • node
  • webpack
web3D😉
宝库📰
  • 分类
  • 标签
  • 归档
龙哥的大🐂之路 (opens new window)
GitHub (opens new window)

wsh

人未老,想养老
首页
  • Agent基础
  • Agent设计模式
  • 基础知识
  • ArkUI
  • UIAbility
  • 组件通信方式
  • 前端缓存
  • React
  • typescript
  • javascript
  • flutter
  • node
  • webpack
web3D😉
宝库📰
  • 分类
  • 标签
  • 归档
龙哥的大🐂之路 (opens new window)
GitHub (opens new window)
  • 基础知识
  • ArkUI
    • 两种开发范式
    • ArkTS在ts的基础上主要扩展了三种能力
    • 基本语法
    • 扩展语法:
      • @Builder/@BuilderParam
      • @Extend/@Styles: 扩展内置组件和封装属性样式,更灵活组合内置组件。
      • stateStyles:多态样式,可以依据组件的内部状态的不同,设置不同样式。
    • 基础组件-ArkUI
      • image 组件
    • 堆叠组件
    • 自定义组件:
      • @LocalBuilder装饰器:维持组件父子关系
  • UIAbility
  • 组件通信方式
  • harmonyOS
2025-01-06
目录

ArkUI

# 两种开发范式

基于ArkTS的声明式开发范式(简称“声明式开发范式”)和兼容JS的类Web开发范式(简称“类Web开发范式”)

# ArkTS在ts的基础上主要扩展了三种能力

  • 基本语法:ArkTS定义了声明式UI描述,自定义组件和动态扩展UI元素的能力,再配合ArkUI开发框架的系统组件以及相关的事件方法,属性方法等共同构成了UI开发的主题。

  • 状态管理:ArkTS 提供了多维的状态管理机制。在UI开发框架中,与UI相关的数据可以在组件内使用,也可以在不同组件层级间传递,比如:父子组件之间,爷孙组件之间,还可以在应用全局范围内传递或跨设备传递。从数据传递形式来看,分为只读单项传递和可变更双向传递。

  • 渲染控制:ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态的UI内容。渲染内容可以从数据源的迭代获取数据,并在每次迭代过程中创建相应的组件。数据懒加载从数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。

# 基本语法

ArkTS 声明式开发范式:

  • 装饰器:用来装饰类、结构体、方法和变量、赋予其特殊含义。比如@Entry、@Component、@State 都是装饰器。@Component是自定义组件,@Entry是入口组件,@State是状态变量,此状态变化会引起ui变更
  • 自定义组件:可复用的ui组件,可组合其他组件
  • UI描述:声明式的方式来描述UI的结构,如上述 build() 方法内部的代码块。
  • 内置组件:框架中默认内置的基础和布局组件。
  • 事件方法:用于添加组件对事件的响应逻辑,统一通过事件方法来进行设置。比如onClick
  • 属性方法:用于组件属性的配置,统一通过属性方法进行设置,如fontSize()、width()、height()、color() 等,可通过链式调用的方式设置多项属性。
  • build方法内可以容纳内置组件和其他自定义组件。

# 扩展语法:

# @Builder/@BuilderParam

  • 特殊的封装UI描述的方法,细粒度的封装和复用UI描述。

  • @Builder: 自定义构建函数:

    • 将重复使用的UI元素抽象成一个方法,并在build方法中调用
    • 使用范围:组件范围、全局范围使用
    • 组件内定义:
     @Entry
     @Component
     struct Index {
       // 组件内
       @Builder MuCOm() {
         Row() {
           Text('111')
         }
       }
    
       build() {
         Column() {
           this.MuCOm()
           MuGlobalCOm()
         }
       }
     }
    
     // 全局  全局声明需要加function关键字,使用时直接写函数名称
     @Builder
     function MuGlobalCOm() {
       Row() {
         Text('global')
       }
     }
    
  • @BuilderParam: 装饰器,用于声明任意UI描述的一个元素,类似于vue里的solt 占位符和React中的children

    • 类似于插槽,@BuilderParam 装饰的方式 只能被@Builder初始化
    • 尾随闭包
      import ListMap from '../view/ListMap'
      @Entry
      @Component
      
      struct Home {
        build() {
          // MuGlobalCOm()
          Column({ space: 20}) {
            ListMap({title:"音乐"}) {
              Text('11')
            }
            ListMap({title:"书法"}) {
              Text('22')
            }
            ListMap({title:"美术"})
          }
        }
      }
      
      @Component
      struct ListMap {
        @Prop title: string;
      
        @BuilderParam ListContent: () => void = this.defaultContent;
      
        @Builder defaultContent () {
          Text('默认展示的内容')
        }
      
        build() {
          Column() {
            Text(this.title)
              .width('100%')
              .height(100)
              .textAlign(TextAlign.End)
            this.ListContent()
          }
          .width('100%')
          .height('100vh')
          .backgroundColor(Color.Gray)
        }
      }
      
      export default ListMap;
      
      
      
  • 具名插槽

    
    import ListMap from '../view/ListMap'
    import ListModel from '../view/ListModel'
    
    @Entry
    @Component
    
    struct Home {
      @Builder ListHeader() {
        Text('header')
      }
    
      @Builder ListFooter() {
        Text('footer')
      }
      build() {
        Column({ space: 20}) {
          ListModel({
            listHeader: this.ListHeader,
            listFooter: this.ListFooter,
          })
        }
      }
    }
    
    @Component
    struct ListModel {
      @BuilderParam listHeader: () => void = this.defaultHeader
      @BuilderParam listFooter: () => void = this.defaultFooter
    
      @Builder defaultHeader() {
        Text('111')
      }
    
      @Builder defaultFooter() {
        Text('footer')
      }
    
      build() {
        Column() {
          this.listHeader()
          Text('content')
          this.listFooter()
        }
    
      }
    }
    
    export default  ListModel
    
    

# @Extend/@Styles: 扩展内置组件和封装属性样式,更灵活组合内置组件。

  • 和@Styles不同,@Extend支持封装指定组件的私有属性、私有事件和自身定义的全局方法
  • 和@Styles不同,@Extend 装修的方法支持参数
  • @Extend装饰的方法参数可以为function,作为Event事件的句柄
  • @Extend的参数可以为状态变量,当状态变量改变时,UI可以正常的被刷新渲染
  • @Extend: 扩展组件的样式、事件,实现复用效果
  • @Extend仅支持在全局定义,不支持在组件内部定义。
  • 语法:
 @Extend(组件名) 
 function ExtendName(参数1....) {
 .属性()
 .事件(()=>{})
 }
 // 使用
 组件(){}
 .ExtendName(参数1...)

示例:

 import { promptAction } from '@kit.ArkUI'

 @Entry
 @Component
 struct ExtendUI {
   build() {
   Column({ space: 20 }) {
     Button('hello World')
       .myBtn(ButtonType.Capsule)
     Button('hello World')
       .myBtn(ButtonType.Circle)
       .width(100)
     Button('hello World')
       .myBtn(ButtonType.Normal)
       .width(100)
   }
   }
 }

 @Extend(Button)
 function myBtn(type: ButtonType){
   .fontColor(Color.Blue)
   .type(type)
   .fontWeight(700)
   .onClick(() => {
     promptAction.showToast({
       message: `ButtonType: ${type}`,
       bottom: 300
     })
   })
 }
  • @Style: 提取通用的事件和属性,支持全局和组件内

  • 语法:

// 组件内
@Styles setStyle() {
  .通用属性()
  .通用事件(()=>{})

}

// 全局
@Styles
function commonStyle() {
  .通用属性()
  .通用事件(()=>{})
}

示例:

  import { promptAction } from '@kit.ArkUI'

  @Entry
  @Component
  struct StyleUI {
    @Styles setColor() {
      .backgroundColor(Color.Black)
      .width(200)
      .height(100)
      .borderRadius(10)
    }
    build() {
      Column({ space: 20 }) {
        Row() {
          Text('test @Style')
            .fontColor(Color.White)
            .textAlign(TextAlign.Center)
            .width('100%')
        }
        .setColor()
      }
      .setSte()
    }
  }
  @Styles
  function setSte() {
    .backgroundColor(Color.Gray)
  }

# stateStyles:多态样式,可以依据组件的内部状态的不同,设置不同样式。

  • stateStyles是属性方法,可以根据UI内部状态来设置样式,类似于css伪类,但语法不同。ArkUI提供以下五种状态:
  • focused:获焦态
  • normal:正常态
  • pressed:按压态
  • disabled:不可用态
  • selected10+:选中态

示例

 Button('aaa')
    .stateStyles({
      pressed: {
        .backgroundColor('#ff707070')
        .width(200)
      },
     })

# 基础组件-ArkUI

# image 组件

加载网络图片,注意需要开启网络权限,预览不限制,真机或者模拟器运行需要申请网络权限 需要在module.json5 配置requestPermissions

 requestPermissions: [{"name" :  "ohos.permission.INTERNET"}],

加载本地图片 $r

import router from '@ohos.router'
@Component
@Entry
struct Index {
  build() {
    Column(){
      Image($r('app.media.app_icon'))
      
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f5f5f5')
  }
}

提示

鸿蒙开发遵循一个原则:一个页面或者自己封装的组件 必须有且只有一个根组件

# 堆叠组件

把一个组件堆叠到另外一个组件上的效果,称为层叠效果或者堆叠效果。 使用语法:

Stack() {
  item1()
  item2()
  item3()
}

默认情况下,最后的组件越叠在最上面, 子组件都在Stack容器内居中堆叠: Alignment.Center,如果需要指定谁在最上层,可以通过zIndex ,越大越在上面

# 自定义组件:

语法:

@Component
struct MyComponent {
  build() {
  
  }
}

基本结构:

  • struct:自定义组件基于struct实现,struct + 自定义组件名 + {} 的组合构成自定义组件,不能有继承关系。
  • @Component:@Component 装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述ui,一个struct只能被一个@Component装饰。
  • build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数

build函数注意事项

  • 不允许声明本地变量
build() {
  // 反例:不允许声明本地变量
  let a: number = 1; // error
}
  • 不允许在UI描述里直接使用console.info,但允许在方法或者函数里使用
build() {
  console.log('test') // error
}
  • 不允许创建本地的作用域
build() {
  // 反例:不允许本地作用域
  {
    ...
  }
}
  • 不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值。
@Component
struct ParentComponent {
  doSomeCalculations() {
  }

  calcTextValue(): string {
    return 'Hello World';
  }

  @Builder doSomeRender() {
    Text(`Hello World`)
  }

  build() {
    Column() {
      // 反例:不能调用没有用@Builder装饰的方法
      this.doSomeCalculations();
      // 正例:可以调用
      this.doSomeRender();
      // 正例:参数可以为调用TS方法的返回值
      Text(this.calcTextValue())
    }
  }
}
  • 不允许switch语法,如果需要使用条件判断,请使用if。
build() {
  Column() {
    // 反例:不允许使用switch语法
    switch (expression) {
      case 1:
        Text('...')
        break;
      case 2:
        Image('...')
        break;
      default:
        Text('...')
        break;
    }
  }
}
  • 不允许使用表达式
build() {
  Column() {
    // 反例:不允许使用表达式
    (this.aVar > 10) ? Text('...') : Image('...')
  }
}

# @LocalBuilder装饰器:维持组件父子关系

# 语法:

@LocalBuilder MyBuilderFunction() { ... }

# 限制条件:

  • @LocalBuilder 只能在所属组件内声明,不允许全局声明
  • @LocalBuilder 不能被内置装饰器和自定义装饰器使用
  • 自定义组件内的静态方法不能和@LocalBuilder 一起使用

# @LocalBuilder 和局部@Builder 使用区别

@Builder方式引用传参时,为了改变this指向,使用bind(this)后,会导致组件的父子关系和状态管理的父子关系不一致,但是@LocalBuilder是否使用bind(this), 都不会改变组件的父子关系

# 参数传递规则

@LocalBuilder 函数的参数传递有按值传递和按引用传递两种,均需遵守一下规则:

  • 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
  • 在@LocalBuilder修饰的函数内部,不允许改变参数值
  • 只有传入一个参数,且参数需要直接传入对象字面量才会按引用传递该参数,其余传递方式均为按值传递

# 按引用传递参数

按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@LocalBuilder方法内的UI刷新。

若子组件调用父组件的@LocalBuilder函数,传入的参数发生变化,不会引起@LocalBuilder方法内的UI刷新

按引用传递参数时,如果在@LocalBuilder方法内调用自定义组件,ArkUI 提供$$作为按引用传递参数的范式

class ReferenceType {
  paramString: string = '';
}

@Component
struct HelloComponent {
  @Prop message: string;

  build() {
    Row() {
      Text(`HelloComponent===${this.message}`);
    }
  }
}

@Entry
@Component
struct Parent {
  @State variableValue: string = 'Hello World';

  @LocalBuilder
  citeLocalBuilder($$: ReferenceType) {
    Row() {
      Column() {
        Text(`citeLocalBuilder===${$$.paramString}`);
        HelloComponent({ message: $$.paramString });
      }
    }
  }

  build() {
    Column() {
      this.citeLocalBuilder({ paramString: this.variableValue });
      Button('Click me').onClick(() => {
        this.variableValue = 'Hi World';
      })
    }
  }
}

# 按值传递参数

调用@LocalBuilder 装饰的函数默认按值传递,当传递的参数为状态变量时,状态变量的改变不会引起@LocalBuilder方法内的UI刷新,所以当使用状态变量是,推荐使用按引用传递

# @LocalBuilder和@Builder区别说明

函数componentBuilder被@Builder修饰时,显示效果是 “Child”,函数componentBuilder被@LocalBuilder修饰时,显示效果是“Parent”。

提示

  • @Builder componentBuilder()通过this.componentBuilder的形式传给子组件@BuilderParam customBuilderParam,this指向在Child的label,即“Child”。

  • @LocalBuilder componentBuilder()通过this.componentBuilder的形式传给子组件@BuilderParam customBuilderParam,this指向Parent的label,即“Parent”。

# 使用场景

@LocalBuilder在@ComponentV2修饰的自定义组件中使用

使用局部的@LocalBuilder在@ComponentV2修饰的自定义组件中调用,修改变量触发UI刷新

#harmonyOS
基础知识
UIAbility

← 基础知识 UIAbility→

最近更新
01
Agent基础
01-13
02
组件通信方式
01-08
03
UIAbility
01-07
更多文章>
Theme by Vdoing | Copyright © 2022-2026 Wsh | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式