HarmonyOS鸿蒙开发 - 一文搞懂 ArkTS

1,519 阅读6分钟

简单介绍

关于我

既然是第一篇文章,那就做个自我介绍,一名写代码有 10 年时间(前端开发 6 年)的 98 年程序员,没什么特别的大厂经历,也没什么文凭,唯一可以炫耀一下的也就是年龄了,14 岁开始接触编程,涉猎过的技术有.net,java,前端等 web 方面较多。

为什么要做这个系列的文章?

鸿蒙作为当下较为火热的新兴技术,目前人才缺口较大,之后需求也会日益增加,随着大厂国企的率先跟进适配,之后可能会成为除 ios,安卓外的另一壁江山(个人猜测,不作担保)。说回正题,写这系列文章一方面是巩固自己的技术,另一方面就是希望能够帮助到初学者更快的了解掌握鸿蒙(大佬勿 cue)。

正文

本人适合有一定开发基础的同学阅读,如学过前端,java 等开发语言

关于 ArkTS

ArkTS 为鸿蒙主推的开发语言,理解为鸿蒙的逻辑处理语言,主要语法基于 Typescript,在这个基础上做了一些扩展,如果说 Typescript 是 JS 的超集的话,那 ArkTS 就是 TS 的超集,建议没有基础的同学看这篇文章之前先去学习一下 TS ,本文就不介绍 TS 的用法了。

文章将分为几个部分来讲清楚 ArkTS 的语法和重点

  • 基本语法
  • 组件
  • 应用状态管理
  • 渲染控制

基本语法

直接先来看代码

// Index.ets
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        // 添加按钮,以响应用户点击
        Button() {
          Text('Next')
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
        }
        .type(ButtonType.Capsule)
        .margin({
          top: 20
        })
        .backgroundColor('#0D9FFB')
        .width('40%')
        .height('5%')
      }
      .width('100%')
    }
    .height('100%')
  }
}

这段代码为一个鸿蒙页面的基本构成,其实已经把主要的 ArkTS 的基本语法都包含在里面了。
@为装饰器的修饰符,@Entry代表一个页面的入口,@Component表示声明了一个组件。
build表示一个组件的构成函数,build中包含的就是 ui 的构成了。

鸿蒙采用的 ui 表达方式就是声明式的写法,名称为ArkUI,写法可以理解为就像 JS 中写函数一样,一级级嵌套,一个基础ui组件里面需要包含什么,就嵌套什么(有的基础组件不能嵌套,详见官方文档),设置一些如颜色,字体大小等属性,或设置一些事件,都以.调用的方式,个人认为还是非常好理解的。

组件

自定义组件由@Component装饰器定义,以下为一个基础组件的构成

@Component
struct HelloComponent {
  @State message: string = 'Hello, World!';

  build() {
    // HelloComponent自定义组件组合系统组件Row和Text
    Row() {
      Text(this.message)
        .onClick(() => {
          // 状态变量message的改变驱动UI刷新,UI从'Hello, World!'刷新为'Hello, ArkUI!'
          this.message = 'Hello, ArkUI!';
        })
    }
  }
}

以下为调用父组件调用这个组件

@Entry
@Component
struct ParentComponent {
  build() {
    Column() {
      Text('ArkUI message')
      HelloComponent({ message: 'Hello, World!' });
      Divider()
      HelloComponent({ message: '你好!' });
    }
  }
}

组件的状态管理
@State装饰器,为状态变量,其定义的变量,能够触发视图UI渲染。

  • 当用于简单类型时,如number,boolean,string,可直接观察到其变化。
  • 当用于Object,class时,可观察到自身赋值的变化,和其属性的变化,但无法观察到嵌套属性的变化。
  • 当用于数组时,数组的增删改都可观察到,但数组项若为一个对象,其属性的变化无法观察到。

@Prop装饰器,父子单向同步变量,父组件变量修改自动同步到子组件,子组件中变量是可变的,但无法同步回其父组件,所以称为单向同步。

@Link装饰器,父子双向同步变量,父组件变量修改自动同步到子组件,子组件的修改同样也会反映到对应父组件的变量。

@Provide装饰器和@Consume装饰器,同 @Link 装饰器也是为父子双向同步,但此组合装饰器可用于祖孙组件同步变量,跨层级,不限层级。

@Observed装饰器和@ObjectLink装饰器,用于解决复杂类型多层属性变化无法观察到的问题

  • 规则:@Observed 为类装饰器,写于 class 定义之前,@ObjectLink 装饰器必须对应 @Observed装饰的类实例,@ObjectLink 装饰的变量本身不能被修改,但其属性是可以修改并是同步的。

@Watch装饰器,用于监听状态变量的更新。

$$ 语法,用于状态变量的双向同步,如有一个 @State 装饰的 a 变量,使用的函数参数定义value:$$this.a,即可使用该value与@State变量同步。

这些就是基本的组件装饰器的用法,具体介绍和细节可以参考官方文档,其中都有代码示例,这里把其中主要的用途说明一下。

应用状态管理

除了组件的状态管理,很多时候我们会碰到需要整个应用,跨页面,跨组件的数据共享需求,arkTS 也提供了对应的能力。

LocalStorage
页面级存储,可用于跨组件,同个页面内的数据共享

  • @LocalStorageProp:@LocalStorageProp装饰的变量和与LocalStorage中给定属性建立单向同步关系。
  • @LocalStorageLink:@LocalStorageLink装饰的变量和在@Component中创建与LocalStorage中给定属性建立双向同步关系。

AppStorage
应用级存储,可用于跨页面,同应用内的数据共享

  • @StorageProp: @StorageProp(key)是和AppStorage中key对应的属性建立单向数据同步。
  • @StorageLink:@StorageLink(key)是和AppStorage中key对应的属性建立双向数据同步。

这两个为常用的存储方式,更多可见官方文档

渲染控制

if else 条件判断

@Component
struct CounterView {
  @State counter: number = 0;
  label: string = 'unknown';

  build() {
    Row() {
      Text(`${this.label}`)
      Button(`counter ${this.counter} +1`)
        .onClick(() => {
          this.counter += 1;
        })
    }
  }
}

@Entry
@Component
struct MainView {
  @State toggle: boolean = true;

  build() {
    Column() {
      if (this.toggle) {
        CounterView({ label: 'CounterView #positive' })
      } else {
        CounterView({ label: 'CounterView #negative' })
      }
      Button(`toggle ${this.toggle}`)
        .onClick(() => {
          this.toggle = !this.toggle;
        })
    }
  }
}

以上代码为通过一个点击事件加上if else条件判断来切换子组件的显示状态,比较好理解。

Foreach 循环

@Entry
@Component
struct Parent {
  @State simpleList: Array<string> = ['one', 'two', 'two', 'three'];

  build() {
    Row() {
      Column() {
        ForEach(this.simpleList, (item: string) => {
          ChildItem({ 'item': item } as Record<string, string>)
        }, (item: string) => item)
      }
      .width('100%')
      .height('100%')
    }
    .height('100%')
    .backgroundColor(0xF1F3F5)
  }
}

@Component
struct ChildItem {
  @Prop item: string;

  build() {
    Text(this.item)
      .fontSize(50)
  }
}

以上为循环渲染一个简单数组

主要是使用到的基本渲染控制介绍完毕,更多内容和细节见官方文档

总结

以上就是基本 ArkTS 的语法和重点了,可能不是特别细,但看完应该能够对 ArkTS 有一个基本了解和概念,也能够上手写一些东西了,建议同学们看完本文再去对应的官方文档补充看一下,这样就能对这个语言有比较全面的理解了,相对来说逻辑上并不会很难,更多的是语法的学习和使用上。

Tips:
第一篇鸿蒙开发文章,写的可能不是很规范和详细,之后会持续更新,提高文章质量,也希望和大家多多交流。