云计算百科
云计算领域专业知识百科平台

HarmonyOS ArkTS 零基础语法讲义:从第一行代码到可运行页面

0.先建立正确认识:ArkTS、TypeScript 与 ArkUI 分别是什么

初学 HarmonyOS 时,最容易混淆的有三个名词:
名称你可以把它理解为主要解决的问题
JavaScript基础编程语言“让程序做事”
TypeScriptJavaScript 加上类型检查“让代码更不容易写错”
ArkTSHarmonyOS 面向应用开发的 TypeScript 方言“用更规范、更安全的方式写 HarmonyOS 代码”
ArkUIHarmonyOS 的声明式 UI 框架“把数据画成页面,并响应用户点击”

一句话记忆:
• ArkTS 是写逻辑、类型和数据的语言。
• ArkUI 是用 ArkTS 描述界面的方式。
• 你在 .ets 文件里通常会同时写“数据处理代码”和“页面代码”。
例如:

let userName: string = '小明'; // ArkTS:定义数据

Text(`你好,${userName}`) // ArkUI:把数据画到屏幕上

1. 第一个页面长什么样

打开新项目中的 Index.ets,常会看到类似下面的结构:

@Entry
@Component
struct Index {
@State message: string = '你好,ArkTS!'

build() {
Column() {
Text(this.message)
.fontSize(28)

Button('点我')
.margin({ top: 16 })
.onClick(() => {
this.message = '你刚刚点击了按钮'
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}

运行后,页面上会显示一句文字和一个按钮。点击按钮,文字会改变。
先不要急着记住全部语法。你只要先理解这四件事:

  • struct Index:定义一个叫 Index 的页面组件。
  • @State message:定义会影响页面显示的数据。
  • build():描述页面“应该长什么样”。
  • onClick:描述用户点击按钮后“应该做什么”。
  • 1.1 @Entry:应用入口页面

    @Entry
    @Component
    struct Index {
    build() {
    Text('我是应用启动后最先显示的页面')
    }
    }

    @Entry 表示:这个组件是一个页面入口。一个页面文件通常只需要一个 @Entry 组件。

    1.2 @Component:这是一个 UI 组件

    @Component
    struct WelcomeCard {
    build() {
    Text('欢迎学习 ArkTS')
    }
    }

    有了 @Component,ArkUI 才知道这个 struct 不是普通数据结构,而是一个可绘制到屏幕上的组件。

    1.3 build():页面的“说明书”

    在 build() 中,你不是手工创建像素,而是在声明:
    页面里有哪些组件,它们按什么顺序排列,使用什么数据,拥有怎样的样式。

    build() {
    Column() {
    Text('第一行')
    Text('第二行')
    Button('第三个控件')
    }
    }

    这段代码表示纵向排列:

    第一行
    第二行
    [第三个控件]

    2. 注释:给未来的自己写说明

    注释不会执行,只是解释代码。

    // 单行注释:这一行不会执行

    /*
    多行注释:
    可以写很多行说明。
    */

    推荐养成两个习惯:
    • 对“为什么这样写”添加注释。
    • 不要给显而易见的语句添加无意义注释。
    不太有帮助:

    let age: number = 18; // 定义年龄

    更有帮助:

    // 订单金额以“分”为单位保存,避免浮点数计算误差
    let amountInFen: number = 1999;

    3. 变量:让程序记住数据

    变量可以理解为“有名字的盒子”。你把数据放进盒子,后续通过名字取出来。
    ArkTS 中最常用的变量声明方式是 let 和 const。

    let score: number = 60;
    score = 95;

    const appName: string = '学习助手';
    // appName = '新名称'; // 错误:const 声明的变量不能重新赋值

    3.1 let 和 const 怎么选

    在这里插入图片描述

    let page: number = 1;
    page = 2;

    const maxPageSize: number = 20;

    初学时可以采用简单规则:
    默认先写 const;只有确实需要改变变量值时,才使用 let。

    3.2 不推荐随意使用 var

    你可能会在旧 JavaScript 教程中看到 var:
    var oldStyle: string = ‘旧写法’;
    现代 ArkTS 开发中优先使用 let 和 const。它们的作用范围更清楚,更不容易产生难以排查的错误。

    4. 基本数据类型:给数据贴上“标签”

    类型告诉编译器:这个变量里准备装什么数据。

    let name: string = '小华';
    let age: number = 18;
    let isStudent: boolean = true;

    4.1 string:文本

    文本必须用单引号、双引号或反引号包起来。

    let city: string = '深圳';
    let school: string = "鸿蒙学院";
    let greeting: string = `欢迎来到 ${city}`;

    推荐使用模板字符串(反引号)拼接文本:

    let userName: string = '小华';
    let age: number = 18;

    let text: string = `我是${userName},今年${age}岁。`;

    不推荐初学时大量使用 + 拼接:
    let text: string = ‘我是’ + userName + ‘,今年’ + age + ‘岁。’;
    模板字符串可读性更好。
    常用文本操作:

    let title: string = ' ArkTS 入门 ';

    let length: number = title.length; // 文本长度
    let upper: string = title.toUpperCase(); // 转大写
    let lower: string = title.toLowerCase(); // 转小写
    let clean: string = title.trim(); // 去掉首尾空格
    let hasArk: boolean = title.includes('Ark'); // 是否包含某文本

    4.2 number:数字

    number 可表示整数和小数。

    let count: number = 10;
    let price: number = 19.9;
    let total: number = count * price;

    常见运算符:
    在这里插入图片描述

    let apples: number = 10;
    apples = apples + 1;
    apples += 1; // 等价于 apples = apples + 1

    4.3 boolean:真或假

    布尔值只有两个:

    let isLogin: boolean = true;
    let isVip: boolean = false;

    注意:true 和 false 不要加引号。加了引号后它们会变成文本。

    let correct: boolean = true;
    let wrong: string = 'true';

    4.4 undefined 与 null:没有值,要谨慎处理

    初学阶段最重要的原则是:
    不确定数据是否存在时,先检查,再使用。

    let nickName: string | undefined = undefined;

    if (nickName !== undefined) {
    console.info(nickName.toUpperCase());
    } else {
    console.info('用户尚未设置昵称');
    }

    string | undefined 的意思是:这个变量要么是文本,要么没有值。

    5. 类型推断:有时可以不手写类型

    如果右侧的值非常明确,ArkTS 通常可以自动推断类型:

    let name = '小明'; // 推断为 string
    let age = 20; // 推断为 number
    let isReady = true; // 推断为 boolean

    不过在学习阶段、函数参数、对象结构、接口边界处,建议明确写出类型:

    let courseName: string = 'ArkTS';
    let lessonCount: number = 12;

    这样你自己和编译器都更容易发现问题。

    6. 运算与比较:程序如何“判断”

    6.1 比较运算符

    let score: number = 85;

    console.info(score > 60); // true
    console.info(score >= 85); // true
    console.info(score < 100); // true
    console.info(score === 85); // true
    console.info(score !== 85); // false

    初学时请优先使用严格相等 === 和严格不等 !==。

    let value: number = 1;

    // 推荐
    if (value === 1) {
    console.info('值为 1');
    }

    6.2 逻辑运算符

    let age: number = 20;
    let hasTicket: boolean = true;

    let canEnter: boolean = age >= 18 && hasTicket;
    let needsHelp: boolean = age < 18 || !hasTicket;

    在这里插入图片描述

    7. 条件判断:让程序做不同选择

    7.1 if / else if / else

    function getLevel(score: number): string {
    if (score >= 90) {
    return '优秀';
    } else if (score >= 60) {
    return '及格';
    } else {
    return '需要继续努力';
    }
    }

    调用:

    let result: string = getLevel(85);
    console.info(result); // 及格

    读代码时可以按自然语言理解:

    如果 分数大于等于 90:优秀
    否则如果 分数大于等于 60:及格
    否则:需要继续努力

    7.2 三元表达式:简单二选一

    当判断只有两个结果时可使用:

    let isLogin: boolean = true;
    let displayText: string = isLogin ? '欢迎回来' : '请先登录';

    格式是:

    条件 ? 条件成立时的值 : 条件不成立时的值

    不要把过于复杂的业务逻辑塞进三元表达式;复杂时请改用 if。

    7.3 switch:多个固定选项

    function getWeekText(day: number): string {
    switch (day) {
    case 1:
    return '星期一';
    case 2:
    return '星期二';
    case 3:
    return '星期三';
    default:
    return '其他日期';
    }
    }

    当你是在比较“一个值对应多个固定情况”时,switch 很合适。

    8. 循环:重复做一件事

    8.1 for 循环

    for (let index: number = 1; index <= 5; index++) {
    console.info(`第 ${index} 次练习`);
    }

    它由三部分组成:

    for (初始化; 继续条件; 每轮结束后的变化) {
    重复执行的代码
    }

    8.2 遍历数组:for…of

    let fruits: string[] = ['苹果', '香蕉', '橙子'];

    for (const fruit of fruits) {
    console.info(fruit);
    }

    对于初学者,读取数组中的每一项时,优先考虑 for…of。它比手动写下标更直观。

    8.3 while 循环

    let current: number = 1;

    while (current <= 3) {
    console.info(`当前值:${current}`);
    current++;
    }

    使用 while 时一定要确保循环条件最终会变成 false,否则可能出现死循环。
    错误示例:

    let count: number = 1;

    // 不要运行这样的代码:count 永远没有变化
    // while (count <= 3) {
    // console.info(count);
    // }

    9. 数组:按顺序保存一组数据

    数组用于保存多个同类数据。

    let scores: number[] = [80, 90, 100];
    let names: string[] = ['小红', '小蓝', '小绿'];

    9.1 读取数组元素

    数组下标从 0 开始:

    let cities: string[] = ['北京', '上海', '广州'];

    console.info(cities[0]); // 北京
    console.info(cities[1]); // 上海

    9.2 常用数组操作

    let tasks: string[] = ['学习变量', '学习函数'];

    tasks.push('学习组件'); // 末尾添加
    console.info(tasks.length);

    let firstTask: string | undefined = tasks.shift(); // 删除并取得第一个元素
    console.info(firstTask);

    在 UI 状态中,推荐返回新数组,而不是就地修改复杂对象。这样页面更新更稳定、代码也更容易理解:

    let oldList: number[] = [1, 2, 3];
    let newList: number[] = oldList.map((item: number) => item * 2);

    // oldList 是 [1, 2, 3]
    // newList 是 [2, 4, 6]

    9.3 常见数组方法

    let scores: number[] = [60, 75, 90, 100];

    let passed: number[] = scores.filter((score: number) => score >= 60);
    let doubled: number[] = scores.map((score: number) => score * 2);
    let hasPerfect: boolean = scores.some((score: number) => score === 100);
    let allPassed: boolean = scores.every((score: number) => score >= 60);

    它们的语义是:
    在这里插入图片描述

    10. 对象:描述一件有多个属性的事物

    如果一个学生不仅有姓名,还有年龄和是否已报名,就适合用对象:

    let student: {
    name: string;
    age: number;
    enrolled: boolean;
    } = {
    name: '小明',
    age: 18,
    enrolled: true
    };

    console.info(student.name);
    console.info(student.age);

    但对象字段较多时,建议使用 interface。

    11. interface:给对象制定统一结构

    接口是一份“数据结构约定”。它不直接创建对象,而是规定对象必须有什么字段、每个字段是什么类型。

    interface Student {
    id: number;
    name: string;
    age: number;
    enrolled: boolean;
    }

    按接口创建对象:

    let student: Student = {
    id: 1,
    name: '小明',
    age: 18,
    enrolled: true
    };

    如果漏掉字段,编译器会提醒你:

    // 错误示意:缺少 enrolled
    // let invalidStudent: Student = {
    // id: 2,
    // name: '小红',
    // age: 19
    // };

    11.1 可选属性 ?

    有些属性可以没有:

    interface UserProfile {
    id: number;
    name: string;
    avatarUrl?: string;
    }

    let user: UserProfile = {
    id: 1,
    name: '小华'
    };

    读取可选属性时要兜底:

    let avatarText: string = user.avatarUrl ?? '未设置头像';
    console.info(avatarText);

    ?? 的意思是:如果左边是 null 或 undefined,就使用右边的默认值。

    12. 函数:把可重复的逻辑装起来

    函数相当于一个可重复调用的小工具。

    function sayHello(): void {
    console.info('你好,ArkTS!');
    }

    调用函数:

    sayHello();

    12.1 带参数的函数

    function greet(name: string): string {
    return `你好,${name}!`;
    }

    let message: string = greet('小明');
    console.info(message);

    这里:
    • name: string 是输入参数。
    • : string 是函数返回值的类型。
    • return 表示把结果交还给调用者。

    12.2 没有返回值:void

    function printWelcome(): void {
    console.info('欢迎开始学习');
    }

    void 表示该函数只做事情,不返回可供保存的结果。

    12.3 多个参数

    function add(left: number, right: number): number {
    return left + right;
    }

    let sum: number = add(3, 5);

    12.4 默认参数

    function createTitle(text: string, prefix: string = '课程:'): string {
    return `${prefix}${text}`;
    }

    console.info(createTitle('ArkTS 入门'));
    console.info(createTitle('ArkUI 布局', '章节:'));

    12.5 箭头函数

    箭头函数常用于按钮点击、数组处理等场景:

    let multiply = (left: number, right: number): number => {
    return left * right;
    };

    console.info(multiply(2, 3));

    当只有一行返回值时可以简写:

    let square = (value: number): number => value * value;
    ArkUI 中你会经常见到:
    Button('点击')
    .onClick(() => {
    console.info('按钮被点击');
    })

    这个 () => {} 就是“点击发生时再执行的函数”。

    13. 类:把数据和行为放在一起

    类适合描述“有状态、有行为”的对象。

    class Counter {
    private value: number = 0;

    increase(): void {
    this.value++;
    }

    getValue(): number {
    return this.value;
    }
    }

    let counter: Counter = new Counter();
    counter.increase();
    console.info(counter.getValue()); // 1

    理解关键字:
    在这里插入图片描述
    初学阶段可以优先掌握 interface 和函数;当业务对象确实需要封装方法与内部状态时,再使用类。

    14. 枚举:给有限选项取名字

    例如任务状态只有三种,与其到处写数字,不如使用枚举:

    enum TaskStatus {
    Todo,
    Doing,
    Done
    }

    let status: TaskStatus = TaskStatus.Doing;

    if (status === TaskStatus.Doing) {
    console.info('任务正在进行');
    }

    枚举让代码更容易读:

    // 不够直观
    let state: number = 1;

    // 更直观
    let state: TaskStatus = TaskStatus.Doing;

    15. 联合类型、类型别名与类型守卫

    15.1 联合类型

    一个值有时可以是多种类型之一:

    let orderId: number | string = 1001;
    orderId = 'A-1002';

    但使用前要先判断真实类型:

    function formatOrderId(id: number | string): string {
    if (typeof id === 'number') {
    return `数字订单:${id}`;
    }
    return `文本订单:${id.toUpperCase()}`;
    }

    这里的 typeof 判断叫做一种类型守卫:它帮助编译器确认某段代码中的实际类型。

    15.2 类型别名 type

    如果一段类型定义比较长,可以取一个名字:

    type CourseLevel = '初级' | '中级' | '高级';

    let level: CourseLevel = '初级';

    这能限制值只能是三个指定文本之一。

    16. 异常处理:预料失败,而不是害怕失败

    程序可能遇到网络失败、数据格式不对、权限不足等问题。对可能抛出异常的逻辑,可以使用 try / catch:

    function parseScore(text: string): number {
    let result: number = Number(text);

    if (Number.isNaN(result)) {
    throw new Error('分数不是有效数字');
    }

    return result;
    }

    try {
    let score: number = parseScore('90');
    console.info(`分数为:${score}`);
    } catch (error) {
    console.error(`处理失败:${String(error)}`);
    }

    初学时先记住这个模式:

    try {
    // 可能失败的代码
    } catch (error) {
    // 失败后的处理
    }

    不要为了“看起来安全”而吞掉错误。至少应记录错误或给用户一个明确提示。

    17. 异步编程:等待耗时操作完成

    网络请求、文件读写、数据库操作通常不会瞬间完成。异步代码允许程序等待结果,而不把页面完全卡住。

    17.1 Promise

    Promise 可以理解为“未来会拿到一个 T 类型的结果”。

    function getCourseName(): Promise<string> {
    return Promise.resolve('ArkTS 零基础课程');
    }

    17.2 async / await

    推荐的异步写法:

    async function loadCourse(): Promise<void> {
    let courseName: string = await getCourseName();
    console.info(courseName);
    }

    含义是:

  • getCourseName() 开始获取数据。
  • await 等待它完成。
  • 得到文本后,赋值给 courseName。
  • 继续执行后面的代码。
    在 ArkUI 中,常见写法如下:
  • async function loadMessage(): Promise<string> {
    return Promise.resolve('异步数据加载完成');
    }

    @Entry
    @Component
    struct AsyncExample {
    @State message: string = '尚未加载'

    build() {
    Column() {
    Text(this.message)

    Button('加载数据')
    .onClick(async () => {
    this.message = '加载中…';
    this.message = await loadMessage();
    })
    }
    }
    }

    提示:真实项目中会把网络请求、错误处理、加载状态和空数据状态都考虑进去;学习阶段先掌握 async、await 和 Promise 的关系即可。

    18. ArkUI 基础布局:页面如何摆放

    最常用的容器有:
    在这里插入图片描述

    18.1 Column

    Column({ space: 12 }) {
    Text('标题')
    Text('内容')
    Button('确认')
    }
    .width('100%')
    .padding(16)

    18.2 Row

    Row({ space: 8 }) {
    Text('用户名:')
    Text('小明')
    }
    .width('100%')

    18.3 Stack

    后写的组件会覆盖在先写的组件上方:

    Stack({ alignContent: Alignment.BottomStart }) {
    Image($r('app.media.app_icon'))
    .width(120)
    .height(120)

    Text('推荐')
    .fontColor(Color.White)
    .backgroundColor(Color.Red)
    .padding(6)
    }

    如果你的项目中没有对应图片资源,可先不运行这段图片示例;Column、Row 和 Text 不依赖额外资源,可以直接运行。

    19. 样式链式调用:组件后面的点号在做什么

    观察下面代码:

    Text('ArkTS')
    .fontSize(24)
    .fontWeight(FontWeight.Bold)
    .fontColor(Color.Blue)
    .margin({ bottom: 12 })

    它表示“创建一个文本”,然后连续设置它的样式。
    常用样式:

    Text('示例文本')
    .fontSize(18)
    .fontColor('#333333')
    .fontWeight(FontWeight.Medium)
    .textAlign(TextAlign.Center)
    .width('100%')
    .padding(12)
    .backgroundColor('#F1F3F5')
    .borderRadius(8)

    常用尺寸单位:
    • 24:通常表示 vp(虚拟像素),适合布局尺寸。
    • ‘100%’:相对父组件宽度或高度。
    • 12:可用于 padding、margin、fontSize 等常用属性。
    初学时不必把所有属性死记硬背。先会查组件的属性提示,并逐步积累。

    20. @State:页面为什么会自动刷新

    @State 是 ArkUI 最重要的入门概念之一。
    @Entry
    @Component
    struct StateExample {
    @State count: number = 0

    build() {
    Column({ space: 12 }) {
    Text(`当前计数:${this.count}`)
    .fontSize(24)

    Button('+1')
    .onClick(() => {
    this.count++;
    })
    }
    }
    }

    点击按钮后,count 变化,页面中的 Text 会自动显示新值。
    可以这样理解:

    @State 数据变化

    ArkUI 发现这个数据被页面使用

    相关 UI 自动重新计算并刷新

    20.1 普通变量与 @State 的差别

    @Component
    struct WrongExample {
    count: number = 0 // 普通字段,不适合作为需要驱动 UI 刷新的页面状态

    build() {
    Column() {
    Text(`${this.count}`)
    Button('+1').onClick(() => {
    this.count++;
    })
    }
    }
    }

    对于“用户点击后要立即反映到界面上”的数据,应使用 @State:

    @State count: number = 0

    20.2 状态设计的小原则

    适合 @State 的数据:
    • 输入框中正在输入的文字。
    • 当前选中的标签。
    • 列表中的任务数据。
    • 加载中、加载成功、加载失败的页面状态。
    • 当前计数、当前页码。
    不适合把所有数据都无脑放进 @State。例如不会影响当前页面展示的常量、工具对象、一次性临时计算结果,通常不需要页面状态装饰。

    21. 组件通信:父组件把数据交给子组件

    21.1 @Prop:父传子,子组件只读使用

    @Component
    struct UserGreeting {
    @Prop name: string = '访客'

    build() {
    Text(`你好,${this.name}`)
    }
    }

    @Entry
    @Component
    struct ParentPage {
    build() {
    Column() {
    UserGreeting({ name: '小明' })
    UserGreeting({ name: '小红' })
    }
    }
    }

    父组件使用子组件时像传参数一样传入:

    UserGreeting({ name: '小明' })

    21.2 @Link:父子共享可修改状态

    当子组件既要展示数据,又要修改父组件的状态,可以使用

    @Link:
    @Component
    struct CounterButton {
    @Link count: number

    build() {
    Button(`子组件加 1:${this.count}`)
    .onClick(() => {
    this.count++;
    })
    }
    }

    @Entry
    @Component
    struct ParentCounterPage {
    @State count: number = 0

    build() {
    Column({ space: 12 }) {
    Text(`父组件计数:${this.count}`)
    .fontSize(24)

    CounterButton({ count: $count })
    }
    .padding(24)
    }
    }

    注意传入时是 $count,不是 count:

    CounterButton({ count: $count })

    初学记忆:
    在这里插入图片描述

    22. 页面渲染语法:条件显示和循环显示

    22.1 if:有条件地显示组件

    @Entry
    @Component
    struct LoginPage {
    @State isLogin: boolean = false

    build() {
    Column({ space: 12 }) {
    if (this.isLogin) {
    Text('欢迎回来!')
    .fontSize(24)
    } else {
    Text('请先登录')
    .fontSize(24)
    }

    Button(this.isLogin ? '退出登录' : '登录')
    .onClick(() => {
    this.isLogin = !this.isLogin;
    })
    }
    .padding(24)
    }
    }

    这里 if 不是普通函数中的条件,而是在 build() 中决定“显示哪一组 UI”。

    22.2 ForEach:把数组画成列表

    @Entry
    @Component
    struct FruitPage {
    @State fruits: string[] = ['苹果', '香蕉', '橙子']

    build() {
    Column({ space: 8 }) {
    ForEach(this.fruits, (fruit: string) => {
    Text(fruit)
    .fontSize(20)
    .width('100%')
    .padding(12)
    .backgroundColor('#F1F3F5')
    .borderRadius(8)
    }, (fruit: string) => fruit)
    }
    .padding(16)
    }
    }

    ForEach 的三个部分:

    ForEach(
    数据数组,
    每一项如何绘制,
    每一项的唯一标识
    )

    最后的唯一标识很重要。真实列表中建议使用稳定的 id,不要只依赖容易重复或变化的文本。

    23. 输入与事件:让用户和页面互动

    23.1 TextInput

    @Entry
    @Component
    struct InputPage {
    @State inputText: string = ''

    build() {
    Column({ space: 12 }) {
    TextInput({ placeholder: '请输入你的名字', text: this.inputText })
    .onChange((value: string) => {
    this.inputText = value;
    })

    Text(this.inputText.length > 0 ? `你好,${this.inputText}` : '还没有输入内容')
    }
    .padding(24)
    }
    }

    核心关系:

    输入框内容变化

    onChange 接收到 value

    更新 @State inputText

    Text 使用新值重新显示

    23.2 常用事件

    Button('点击')
    .onClick(() => {
    console.info('点击事件');
    });

    TextInput({ placeholder: '输入内容' })
    .onChange((value: string) => {
    console.info(`输入内容:${value}`);
    });

    事件函数不要写成立即执行:

    // 错误示意:不要这样写
    // .onClick(this.doSomething())

    应该传入一个函数:

    .onClick(() => {
    this.doSomething();
    })

    24. 资源引用:$r() 是什么

    HarmonyOS 项目中的资源通常放在 resources 目录。引用字符串、颜色、图片等资源时,经常会看到 $r():

    Text($r('app.string.app_name'))

    Image($r('app.media.app_icon'))

    可以粗略理解为:
    “到应用资源文件中,按资源名取出对应内容。”
    初学阶段,直接使用文本和颜色即可:

    Text('欢迎学习 ArkTS')
    .fontColor('#0A59F7')

    当项目需要多语言、统一主题和可维护图片资源时,再逐步学习资源文件的组织方式。

    25. ArkTS 初学者最常遇到的错误

    25.1 把文本忘记加引号

    // 错误
    // let name: string = 小明;

    // 正确
    let name: string = '小明';

    25.2 把 = 与 === 混淆

    let score: number = 90;

    // 正确:比较
    if (score === 90) {
    console.info('满分');
    }

    • =:赋值。
    • ===:比较是否相等。

    25.3 忘记使用 this

    在组件内部访问字段时通常要写 this.:

    @State count: number = 0

    // 正确
    this.count++;

    25.4 把会改变页面的变量写成普通字段

    // 要让 UI 自动刷新,使用 @State
    @State title: string = '初始标题';

    25.5 ForEach 中没有稳定唯一标识

    列表有增加、删除、排序等操作时,尽量使用业务唯一 id:

    interface Todo {
    id: number;
    title: string;
    }

    ForEach(this.todos, (item: Todo) => {
    Text(item.title)
    }, (item: Todo) => item.id.toString())

    25.6 把复杂业务全塞进 build()

    build() 应主要负责描述 UI。复杂计算、数据转换、网络调用可以提取成函数:

    private getWelcomeText(): string {
    return this.userName.length > 0 ? `你好,${this.userName}` : '你好,访客';
    }

    build() {
    Text(this.getWelcomeText())
    }

    26. 完整可运行示例:ArkTS 语法实验室

    把下面完整代码复制到 entry/src/main/ets/pages/Index.ets,替换原有内容后运行。点击按钮即可在页面上看到变量、数组、对象、函数、类、枚举和异步语法的执行结果。

    enum LearningStatus {
    NotStarted,
    Learning,
    Finished
    }

    interface Learner {
    name: string;
    age: number;
    courses: string[];
    }

    class SimpleCounter {
    private value: number = 0;

    increase(): void {
    this.value++;
    }

    getValue(): number {
    return this.value;
    }
    }

    function getLevel(score: number): string {
    if (score >= 90) {
    return '优秀';
    } else if (score >= 60) {
    return '及格';
    }
    return '继续努力';
    }

    function getAsyncMessage(): Promise<string> {
    return Promise.resolve('异步任务已完成:你已经掌握了 async / await 的基本写法。');
    }

    @Entry
    @Component
    struct Index {
    @State resultText: string = '点击“运行示例”,在这里查看输出。'

    build() {
    Column({ space: 16 }) {
    Text('ArkTS 语法实验室')
    .fontSize(26)
    .fontWeight(FontWeight.Bold)

    Text(this.resultText)
    .fontSize(16)
    .lineHeight(24)
    .width('100%')
    .padding(16)
    .backgroundColor('#F1F3F5')
    .borderRadius(12)

    Button('运行示例')
    .width('100%')
    .onClick(async () => {
    await this.runDemo();
    })
    }
    .width('100%')
    .height('100%')
    .padding(24)
    .justifyContent(FlexAlign.Center)
    }

    private async runDemo(): Promise<void> {
    const appName: string = 'ArkTS 入门';
    let score: number = 88;
    const isLearning: boolean = true;

    const learner: Learner = {
    name: '小明',
    age: 18,
    courses: ['变量', '函数', '组件']
    };

    const counter: SimpleCounter = new SimpleCounter();
    counter.increase();
    counter.increase();

    const status: LearningStatus = LearningStatus.Learning;
    const courseText: string = learner.courses.join('、');
    const level: string = getLevel(score);
    const asyncMessage: string = await getAsyncMessage();

    this.resultText =
    `课程:${appName}\\n` +
    `学习者:${learner.name},${learner.age} 岁\\n` +
    `正在学习:${isLearning ? '是' : '否'}\\n` +
    `课程列表:${courseText}\\n` +
    `分数:${score},评价:${level}\\n` +
    `计数器值:${counter.getValue()}\\n` +
    `学习状态枚举值:${status}\\n` +
    `${asyncMessage}`;
    }
    }

    你可以尝试自己修改:

  • 把 score 改成 95,观察评价变化。
  • 在 courses 中增加 ‘异步编程’。
  • 多调用一次 counter.increase()。
  • 把 learner.name 改成你自己的名字。
  • 27 一份速查表

    在这里插入图片描述
    在这里插入图片描述

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » HarmonyOS ArkTS 零基础语法讲义:从第一行代码到可运行页面
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!