鸿蒙开发入门学习记录(二):ArkTS 语法与声明式 UI 上手
·
鸿蒙开发入门学习记录(二):ArkTS 语法与声明式 UI 上手
鸿蒙开发入门学习记录(二):ArkTS 语法与声明式 UI 上手
系列导航:
(一)环境搭建与第一个 Hello World ·
(二)ArkTS 语法与声明式 UI 上手 ·
前言
上一篇我们跑通了 Hello World,对声明式 UI 有了初步感受。本篇正式进入语言层面:先掌握 ArkTS 的基础语法,再搞懂 声明式 UI 的写法(组件、属性、事件、布局),最后用两个小例子练手。
本篇目标:看完后能独立写出"输入框 + 按钮 + 列表"这类基础交互页面。
一、ArkTS 是什么
ArkTS 是鸿蒙应用开发的主力语言,它基于 TypeScript 生态做了扩展,核心增加的能力包括:
- 声明式 UI 描述:在代码里直接描述界面结构;
- 自定义组件:把 UI 封装成可复用组件;
- 状态管理:通过装饰器让 UI 随数据自动刷新;
- 渲染控制:条件渲染(
if/else)、循环渲染(ForEach)。
一句话:会 TS/JS 的同学上手很快,ArkTS 在类型上更严格、更偏静态约束(比如默认禁止 any、变量必须初始化等)。
二、ArkTS 基础语法速览
1. 变量与基本类型
// 显式声明类型
let age: number = 25;
let name: string = '小明';
let isDone: boolean = false;
// 类型推断:省略类型注解,编译器自动推断
let score = 98.5; // number
const appName = '学习记录'; // string,const 常量不可重新赋值
// 数组
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ['Alice', 'Bob'];
// 对象(interface 定义结构)
interface User {
id: number;
name: string;
age?: number; // ? 表示可选属性
}
let user: User = { id: 1, name: '张三' };
// 联合类型
let value: number | string = 100;
value = '一百'; // 合法
// 枚举
enum Level { Low, Medium, High }
let lv: Level = Level.Medium;
注意:ArkTS 要求变量必须有确定类型(要么显式标注,要么能推断出来),不允许使用
any逃逸类型检查。
2. 函数
// 普通函数
function add(a: number, b: number): number {
return a + b;
}
// 箭头函数(鸿蒙代码里非常常见,事件回调基本都用它)
const multiply = (a: number, b: number): number => a * b;
// 默认参数与可选参数
function greet(name: string, title: string = '同学', suffix?: string): string {
return `你好,${title} ${name}${suffix ?? ''}`;
}
console.log(greet('小明')); // 你好,同学 小明
console.log(greet('小明', '老师')); // 你好,老师 小明
3. 类与接口
ArkTS 完全支持面向对象:
interface Animal {
name: string;
speak(): void;
}
class Dog implements Animal {
name: string;
private age: number = 2; // 访问修饰符:private / public / protected
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log(`${this.name} 在汪汪叫`);
}
getAge(): number {
return this.age;
}
}
const dog = new Dog('旺财');
dog.speak(); // 旺财 在汪汪叫
4. 空安全:? 和 !
ArkTS 强调空安全,对象或变量可能是空值时需要用 ? 保护,确认不为空时用 ! 断言:
let maybeName: string | undefined = undefined;
// 可选链:可能为空的调用用 ?.
console.log(maybeName?.length); // 不报错,输出 undefined
// 空值合并:为空时给默认值
const len = maybeName?.length ?? 0;
// 非空断言:我确定它不为空(慎用,空时会崩溃)
// console.log(maybeName!.length);
三、声明式 UI 的核心写法
1. 一个页面的"母版"结构
@Entry
@Component
struct MyPage {
// ① 状态变量(数据)
@State count: number = 0;
// ② 界面描述(build 里写 UI)
build() {
Column() {
Text(`点击了 ${this.count} 次`)
}
}
// ③ 方法(业务逻辑)
increment() {
this.count++;
}
}
build() 的硬性规则(写多了会自然记住):
@Entry组件的build()根节点必须且唯一,且必须是容器组件(Column、Row、Flex、Scroll 等);- 普通
@Component组件根节点可以是非容器组件(比如直接是 Text); ForEach不能作为根节点。
2. 组件的三种用法
build() {
Column({ space: 10 }) { // ① 无参/有参创建
// ② 有参:Text 传入字符串
Text('我是文本')
// ③ 属性配置(链式调用)
Text('大字号红色文本')
.fontSize(30)
.fontColor('#FF0000')
.fontWeight(FontWeight.Bold)
// ④ 事件:onClick 点击事件
Button('点我')
.onClick(() => {
console.info('被点击了');
})
// ⑤ 子组件:在容器里放多个子组件(上面的都是 Column 的子组件)
}
}
3. 常用布局容器
| 容器 | 排列方向 | 典型场景 |
|---|---|---|
Column() | 纵向排列 | 页面从上到下布局 |
Row() | 横向排列 | 一行放多个元素 |
Flex() | 弹性布局 | 更灵活的排列方式 |
Scroll() | 可滚动容器 | 内容超出屏幕时 |
List() + ListItem() | 长列表 | 聊天记录、商品列表 |
// Row + Column 组合,这是最常用的布局套路
build() {
Column({ space: 20 }) {
Row({ space: 10 }) {
Text('左')
Text('中')
Text('右')
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween) // 主轴两端对齐
Divider() // 分割线
}
.width('100%')
.padding(16)
}
4. 常用基础组件
build() {
Column({ space: 16 }) {
// 文本
Text('Hello ArkUI')
// 按钮:支持默认样式和自定义样式
Button('默认按钮')
Button('胶囊按钮', { type: ButtonType.Capsule })
// 输入框
TextInput({ placeholder: '请输入用户名' })
.onChange((value: string) => {
console.info(`输入了:${value}`);
})
// 图片(网络图或本地资源)
Image($r('app.media.icon')) // 本地资源图片
.width(80)
.height(80)
.borderRadius(40)
// 复选框
Checkbox()
.select(false)
.onChange((checked: boolean) => {
console.info(`选中状态:${checked}`);
})
}
}
5. 列表渲染:ForEach
展示动态数组,必须用 ForEach 循环渲染:
@Entry
@Component
struct ListPage {
@State fruits: string[] = ['苹果', '香蕉', '橘子', '西瓜'];
build() {
Column() {
// ① 数据源 ② 渲染函数(每个元素怎么显示) ③ 键值生成器(尽量唯一,用于复用优化)
ForEach(this.fruits, (item: string) => {
Row() {
Text(item)
.fontSize(20)
}
.width('100%')
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(8)
}, (item: string) => item) // 键值生成器:用内容本身做 key
}
.width('100%')
.padding(16)
}
}
6. 条件渲染:if / else
@Entry
@Component
struct LoginPage {
@State isLoggedIn: boolean = false;
build() {
Column() {
if (this.isLoggedIn) {
Text('欢迎回来!')
.fontSize(24)
} else {
Button('点击登录')
.onClick(() => {
this.isLoggedIn = true;
})
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
四、练手:计数器 + 登录表单
例子 1:计数器(状态 + 事件)
@Entry
@Component
struct CounterPage {
@State count: number = 0;
build() {
Column({ space: 24 }) {
Text(`${this.count}`)
.fontSize(64)
.fontWeight(FontWeight.Bold)
Row({ space: 16 }) {
Button('-')
.onClick(() => {
if (this.count > 0) {
this.count--;
}
})
Button('+')
.onClick(() => {
this.count++;
})
}
if (this.count === 10) {
Text('到达 10 啦,真棒!')
.fontColor('#FF9500')
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
例子 2:登录表单(输入框 + 按钮 + 条件显示)
@Entry
@Component
struct LoginFormPage {
@State username: string = '';
@State password: string = '';
@State tip: string = '';
build() {
Column({ space: 16 }) {
Text('鸿蒙登录 Demo')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
TextInput({ placeholder: '请输入用户名', text: this.username })
.onChange((value: string) => {
this.username = value;
})
TextInput({ placeholder: '请输入密码', text: this.password })
.type(InputType.Password)
.onChange((value: string) => {
this.password = value;
})
Button('登录')
.width('100%')
.onClick(() => {
if (this.username === 'admin' && this.password === '123456') {
this.tip = '登录成功!';
} else {
this.tip = '用户名或密码错误';
}
})
if (this.tip !== '') {
Text(this.tip)
.fontColor(this.tip === '登录成功!' ? '#00B42A' : '#F53F3F')
}
}
.width('100%')
.padding(24)
}
}
小经验:
TextInput用text: this.username把输入值"绑"回状态变量,再用onChange同步——这是声明式开发里"受控输入"的标准写法。
五、本篇踩坑记录
- 忘了
this:在 build() 里引用状态变量必须写this.xxx,漏掉会报未定义; - 字符串模板用反引号:
${this.count}必须写在反引号`里,单双引号都不行; - @State 变量要有初始值:ArkTS 不允许声明了不初始化;
- ForEach 的键值生成器要稳定唯一:用数组下标做 key 在增删时容易出问题,尽量用内容或 id;
- 属性要链式调用:
.fontSize(30).fontColor('#333')一个点接一个点写,不能写成赋值。
六、小结与下篇预告
本篇掌握了:
- ✅ ArkTS 基础语法:变量、类型、函数、类、空安全
- ✅ 声明式 UI 写法:build()、组件、属性、事件、子组件
- ✅ 常用容器与组件:Column/Row/List、Text/Button/TextInput/Image
- ✅ 渲染控制:if/else 条件渲染、ForEach 循环渲染
- ✅ 两个小例子:计数器、登录表单
下一篇:进入鸿蒙开发的进阶核心——状态管理(@State/@Prop/@Link/@Provide/@Consume 等装饰器)和页面导航(Navigation),并综合实战一个完整的待办清单 App。
参考资料:
- 华为官方:UI 开发(ArkTS 声明式开发范式)概述 — https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-development-overview
- 华为官方:声明式 UI 描述 — https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/arkts-declarative-ui-description
- 华为官方:创建自定义组件 — https://device.harmonyos.com/cn/docs/apiref/harmonyos-guides/arkts-create-custom-components
如果对你有帮助,欢迎点赞收藏,下一篇见!
更多推荐

所有评论(0)