harmony:基本使用

简介: HarmonyOS提供了一套强大的UI开发框架——方舟开发框架(ArkUI),支持ArkTS声明式开发范式和类Web开发范式。ArkUI框架不仅提供了丰富的组件、布局计算、动画能力和UI交互等功能,还针对不同开发者需求提供了灵活的开发方式。项目结构清晰,包括entry模块、ArkTS源码目录、页面定义、资源文件管理等。此外,还支持自定义组件、装饰器、生命周期管理、路由跳转等高级特性,极大提升了开发效率和应用性能。

简介

官方的解释

UI框架

HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。方舟开发框架可为开发者提供应用UI开发所必需的能力,比如多种组件、布局计算、动画能力、UI交互、绘制等。

方舟开发框架针对不同目的和技术背景的开发者提供了两种开发范式,分别是基于ArkTS的声明式开发范式(简称“声明式开发范式”)和兼容JS的类Web开发范式(简称“类Web开发范式”)。以下是两种开发范式的简单对比。

ArkTS是一种为构建高性能应用而设计的编程语言。ArkTS在继承TypeScript语法的基础上进行了优化,以提供更高的性能和开发效率。

项目结构

entry:HarmonyOS工程模块,编译构建生成一个HAP包。

src > main > ets:用于存放ArkTS源码。

src > main > ets > entryability:应用/服务的入口。

src > main > ets > entrybackupability:应用提供扩展的备份恢复能力。

src > main > ets > pages:应用/服务包含的页面。

src > main > resources:用于存放应用/服务所用到的资源文件,如图形、多媒体、字符串、布局文件等。关于资源文件,详见资源分类与访问。

src > main > module.json5:模块配置文件。主要包含HAP包的配置信息、应用/服务在具体设备上的配置信息以及应用/服务的全局配置信息。具体的配置文件说明,详见module.json5配置文件。

build-profile.json5:当前的模块信息 、编译信息配置项,包括buildOption、targets配置等。

hvigorfile.ts:模块级编译构建任务脚本。

obfuscation-rules.txt:混淆规则文件。混淆开启后,在使用Release模式进行编译时,会对代码进行编译、混淆及压缩处理,保护代码资产。详见开启代码混淆。

oh-package.json5:用来描述包名、版本、入口文件(类型声明文件)和依赖项等信息。

oh_modules:用于存放三方库依赖信息。

build-profile.json5:工程级配置信息,包括签名signingConfigs、产品配置products等。其中products中可配置当前运行环境,默认为HarmonyOS。

hvigorfile.ts:工程级编译构建任务脚本。

oh-package.json5:主要用来描述全局配置,如:依赖覆盖(overrides)、依赖关系重写(overrideDependencyMap)和参数化配置(parameterFile)等。


基本组件

按钮

  Button() {

         Text('Next')

           .fontSize(30)

           .fontWeight(FontWeight.Bold)

       }

       .type(ButtonType.Capsule)

       .margin({

         top: 20

       })

       .backgroundColor('#0D9FFB')

       .width('40%')

       .height('5%')

       // 跳转按钮绑定onClick事件,点击时跳转到第二页

       .onClick(() => {

         console.info(`Succeeded in clicking the 'Next' button.`)

         // 跳转到第二页

         router.pushUrl({ url: 'pages/Second' }).then(() => {

           console.info('Succeeded in jumping to the second page.')

         }).catch((err: BusinessError) => {

           console.error(`Failed to jump to the second page. Code is ${err.code}, message is ${err.message}`)

         })

       })

arkts

装饰器

@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())
    }
  }
}

@Builder装饰器:自定义构建函数

装饰器:用于装饰类、结构、方法以及变量,并赋予特殊含义。如上述的代码片段中@Entry/@Component/@State都属于装饰器,@表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组件中的状态变量,类似于赋予变量响应式,状态变量值发生变化会触发组件更新。


struct:自定义组件基于struct实现,struct + 自定义组件名 + {...}的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。

                                         、

                                       

                                         @Component:@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。

                                       

                                         build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。

                                       

 

                                           @Entry:@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。@Entry可以接受一个可选的LocalStorage的参数。


所有声明在build()函数的语句,我们统称为UI描述,UI描述需要遵循以下规则:


@builder

//在组件外定义words构建函数
@Entry
@Component
struct Index {
  @State message: string = '@Builder \n 组件内构建函数'
  //设置状态变量,方便在选中诗词时能够作为标志位,默认未选中
  @State isChoose: boolean = false
  //  这个是用来创建一个容器的 用来创建组件更好
  @Builder words(content:string){
    Row(){
      Image(this.isChoose ? $r('app.media.foreground') : $r('app.media.startIcon'))
        .width(35)
        .margin(15)
      //构建函数调用自己的形式参数时不需要使用this引用
      Text(content)
        .fontSize(25)
        .decoration({type:this.isChoose ? TextDecorationType.LineThrough : TextDecorationType.None})
    }
    .backgroundColor(Color.Orange)
    .padding(5)
    .borderRadius(25)
    .width('85%')
    .height(70)
    .margin({
      top:10
    })
    //给row组件加上点击事件
    .onClick(()=>{
      this.isChoose = !this.isChoose
    })
  }
  build() {
    Row() {
      Column({space:20}) {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .textAlign(TextAlign.Center)  //设置文本居中显示
        //在组件内调用组件内定义的构建函数:由于该构建函数属于组件内的一部分,因此需要使用this进行调用
        this.words('是造物者之无尽藏也,')
        this.words('而吾与子之所共适!')
        //调用组件外构建函数
        // words2('是造物者之无尽藏也,')
        // words2('而吾与子之所共适!')
      }
      .width('100%')
    }
    .height('100%')
  }
}
 let isChoose = false
//创建组件外构建函数:必须加上关键字function
@Builder function words2(content:string){
  Row(){
    Image(isChoose ? $r('app.media.layered_image') : $r('app.media.background'))
      .width(35)
      .margin(15)
    //构建函数调用自己的形式参数时不需要使用this引用
    Text(content)
      .fontSize(25)
      .decoration({type:isChoose ? TextDecorationType.LineThrough : TextDecorationType.None})
  }
  .backgroundColor(Color.Pink)
  .padding(5)
  .borderRadius(25)
  .width('85%')
  .height(70)
  .margin({
    top:10
  })
  //给row组件加上点击事件
  .onClick(()=>{
    isChoose = !isChoose
  })
}

自定义组件


创建一个 component 文件 下面 放组件

@Component
export struct MyButton {
  @State count: number = 0;
  @State btnName: string = 'click me'
  build() {
    Column() {
      // text 只能 放 string 类型
      Text(''+this.count)
      Divider()
      // 直接使用便可以了
      Button(this.btnName)
        .onClick(() => {
          this.count += 1;
        })
    }
    .width("100%")
    .height("100%")
  }
}

引用和 使用 像vue 一样

//  可以直接使用名字,会自动引用
import { MyButton } from '../Component/MyButton';
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  build() {
      Column(){
        Text("this is father")
        MyButton({
          //里面 定义的变量名 加上 就可以了
          btnName:'father button'
        })
    }.height('100%')
    .width('100%')
  }
}


生命周期

onCreate

如用户打开电池管理应用,在应用加载的过程中,在UI界面出现之前,可以在onCreate回调中读取;
在Create状态,在UIAbility实例创建时触发,系统会调用onCreate回调。

在onWindowStageCreate(windowStage)中通过loadContent接口设置应用要加载的页面。

在UIAbility的UI页面完全不可见之后,即UIAbility切换⾄后台时候触发;

当地图应用切换到后台状态,可以在onBackground回调中停止定位功能,以节省系统的资源消耗;

可以在onBackground回调中释放UI页面不可见时无用的资源,或者在此回调中执行较为耗时的操作。

路由

简单的跳转

// Index.ets
// 导入页面路由模块
import { router } from '@kit.ArkUI';
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  build() {
      Column(){
        Text("this is father")
        Button('跳转').onClick(()=>{
          router.pushUrl({
            url:'pages/Demo'
            // params:{
            //   id:'index',
            //   data:10
            // }
          }).then(()=>{
            console.log(
              "成功");
          })
        })
    }.height('100%')
    .width('100%')
  }
}
@Entry
@Component
struct Demo {
  build() {
    Column(){
      Text("this is child")
    }.height('100%')
    .width('100%')
  }
}

管理路由的页面


跳转加参数

// Index.ets
// 导入页面路由模块
import { router } from '@kit.ArkUI';
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  build() {
      Column(){
        Text("this is father")
        Button('跳转').onClick(()=>{
          router.pushUrl({
            url:'pages/Demo',
            params:{
              id:'index',
              data:10
            }
          }).then(()=>{
            console.log(
              "成功");
          })
        })
    }.height('100%')
    .width('100%')
  }
}
import { router } from '@kit.ArkUI';
// 定义参数的结构
interface ParamsFromIndex {
  index?: string; // 假设 index 是一个可选的字符串
  id?: string;
  // 其他参数可以在这里添加
}
@Entry
@Component
struct Demo {
  @State message: string = "second page";
  @State paramsFromIndex: ParamsFromIndex = router.getParams() as ParamsFromIndex; // 明确类型
  build() {
    Column() {
      Button('click me').onClick(() => {
        console.log(this.paramsFromIndex.id); // 访问 index
      });
    }.height('100%')
    .width('100%');
  }
}

函数

基本使用通过


function print(name?: string) {
  if (name == undefined) {
    console.log('Hello!');
  } else {
    console.log(`Hello, ${name}!`);
  }
}
      Button("click me").onClick(()=>{
        print("youren")
      })
function sum(...numbers: number[]): number {
  let res = 0;
  for (let n of numbers)
    res += n;
  return res;
}
      Button("click me").onClick(()=>{
       let a = sum(1, 2, 3) // 返回6
        console.log(''+a)
      })
function foo(x: number): void;            /* 第一个函数定义 */
function foo(x: string): void;            /* 第二个函数定义 */
function foo(x: number | string): void {  /* 函数实现 */
}
foo(123);     //  OK,使用第一个定义
foo('aa'); // OK,使用第二个定义


class Person {
  name: string = ''
  surname: string = ''
  constructor (n: string, sn: string) {
    this.name = n;
    this.surname = sn;
  }
  fullName(): string {
    return this.name + ' ' + this.surname;
  }
}
let p = new Person('John', 'Smith');
console.log(p.fullName());









相关文章
|
7月前
|
XML 存储 JSON
CocosCreator 面试题(十五)Cocos Creator如何内置protobuf JS版本?
CocosCreator 面试题(十五)Cocos Creator如何内置protobuf JS版本?
190 0
|
11天前
|
JavaScript 前端开发 Python
python中的platform模块的基本使用
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。博客分享前端技术,助你成长。关注我,持续更新中!🎉🎉🎉
|
6月前
|
Android开发 Kotlin
kotlin安卓开发【Jetpack Compose】:封装SnackBarUtil工具类方便使用
GPT-4o 是一个非常智能的模型,比当前的通义千问最新版本在能力上有显著提升。作者让GPT开发一段代码,功能为在 Kotlin 中使用 Jetpack Compose 框架封装一个 Snackbar 工具类,方便调用
|
JavaScript
【第一篇】NodeJs模块篇——Path模块的基本使用|梦小慀
path 是 node.js 官方提供的一个对路径处理很实用的工具模块,多种函数对来访问文件系统并与文件系统进行交互。
208 1
【第一篇】NodeJs模块篇——Path模块的基本使用|梦小慀
|
开发工具
AndroidStudio插件开发(进阶篇之Editor)
AndroidStudio插件开发(进阶篇之Editor)
AndroidStudio插件开发(进阶篇之Editor)
|
Go API 开发工具
beego的安装和简单使用
beego 安装 升级 bee bee工具的安装 使用 bee bee new bee api bee run bee pack bee version
552 0
|
Java Serverless Go
Go原生插件使用问题全解析
本人在设计和落地基于Go原生插件机制的扩展开发产品时踩到了很多坑,由于这方面相关资料很少,因而借此机会做一个非常粗浅的总结,希望能对大家有所帮助。本文只说问题和解决方案,不读代码。
Go原生插件使用问题全解析
|
算法 Java 专有云
Go 原生插件使用问题全解析
我在主导设计和落地基于 Go 原生插件机制的扩展能力时遇到了很多问题,鉴于这方面的相关资料很少,因而就有了这个想法来做一个非常粗浅的总结,希望能对大家有所帮助。
Go 原生插件使用问题全解析
|
数据库 数据库管理 Python
Python:masonite初体验TodoList
Python:masonite初体验TodoList
223 0
Python:masonite初体验TodoList