HarmonyOS 5开发从入门到精通(二):ArkTS语言基础与声明式UI
HarmonyOS 5开发从入门到精通(二):ArkTS语言基础与声明式UI
一、ArkTS语言特性
ArkTS是HarmonyOS应用开发的首选语言,它在TypeScript的基础上进行了扩展,专门为声明式UI开发而设计。ArkTS的核心特点包括:
- 强类型系统:支持类型推断和类型检查,减少运行时错误
- 装饰器语法:通过装饰器(如@Entry、@Component、@State)简化代码编写
- 声明式UI:通过描述UI与数据的映射关系,而非具体操作步骤
- 响应式编程:数据变化自动触发UI更新
二、声明式UI开发范式
2.1 声明式与命令式的区别
命令式开发(传统方式):
// 伪代码示例
const textView = new TextView();
textView.setText("点击计数:0");
button.setOnClickListener(() => {
textView.setText(`点击计数:${++count}`);
});
声明式开发(ArkTS方式):
@Component
struct CounterPage {
@State count: number = 0;
build() {
Column() {
Text(`点击计数:${this.count}`)
Button('增加')
.onClick(() => {
this.count++;
})
}
}
}
声明式开发的核心优势在于:开发者只需描述UI在不同状态下的最终效果,无需关注界面变化的具体过程。
2.2 核心三要素
| 要素 | 作用 | 典型应用场景 |
|---|---|---|
| 数据驱动 | UI随数据自动更新 | 实时数据展示、表单输入 |
| 组件化 | 高内聚、可复用单元 | 公共控件封装、业务模块拆分 |
| 状态管理 | 跨组件数据同步机制 | 全局配置、用户登录状态 |
三、@State装饰器详解
3.1 基本用法
@State是ArkUI框架中最基础的状态管理装饰器,用于管理组件内部的状态。
@Entry
@Component
struct Index {
// 定义状态变量
@State message: string = 'Hello World';
@State count: number = 0;
build() {
Column() {
Text(this.message)
.fontSize(30)
.fontWeight(FontWeight.Bold)
Text(`计数: ${this.count}`)
.fontSize(20)
Button('增加计数')
.onClick(() => {
this.count++;
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
核心特性:
- 组件私有状态:仅在声明它的组件内部有效
- 响应式更新:状态变化自动触发UI更新
- 支持多种数据类型:包括基本类型、类、数组等
3.2 状态管理原理
@State的响应式机制基于依赖收集和变更通知两大核心流程:
- 依赖收集:当组件渲染时,框架会追踪所有被@State修饰的变量在UI组件中的使用情况
- 变更通知:当状态变量被改变时,查询依赖该状态变量的组件,执行更新方法
- 局部刷新:和该状态变量不相关的组件不会重新渲染,实现按需更新
四、常用基础组件
4.1 Text文本组件
Text组件用于在界面上显示文本信息,支持丰富的样式配置。
Text('Hello HarmonyOS')
.fontSize(20) // 字体大小
.fontColor(Color.Red) // 字体颜色
.fontWeight(FontWeight.Bold) // 字体粗细
.textAlign(TextAlign.Center) // 文本对齐
.maxLines(2) // 最大行数
.textOverflow({ // 溢出处理
overflow: TextOverflow.Ellipsis
})
.backgroundColor('#F0F8FF') // 背景颜色
.padding(10) // 内边距
.borderRadius(8) // 圆角
常用属性:
fontSize:字体大小(单位:fp)fontColor:字体颜色fontWeight:字体粗细(Normal、Bold等)textAlign:文本对齐方式(Start、Center、End)maxLines:最大显示行数textOverflow:溢出处理方式(Clip、Ellipsis)
4.2 Image图片组件
Image组件用于显示图片,支持本地和网络图片。
// 显示本地图片
Image($r('app.media.icon'))
.width(100)
.height(100)
.borderRadius(15)
.objectFit(ImageFit.Cover) // 图片填充模式
// 显示网络图片(需要网络权限)
Image('https://example.com/image.jpg')
.width(200)
.height(200)
objectFit填充模式:
ImageFit.Contain:等比缩放,保持宽高比,可能留白ImageFit.Cover:等比缩放,填充整个容器,可能裁剪ImageFit.Fill:拉伸填充,可能变形
4.3 Button按钮组件
Button组件用于用户交互,支持多种样式和事件处理。
Button('点击我')
.width(200)
.height(60)
.fontSize(20)
.backgroundColor('#007DFF')
.fontColor(Color.White)
.type(ButtonType.Capsule) // 胶囊样式
.stateEffect(true) // 点击效果
.onClick(() => {
console.log('按钮被点击了');
// 执行点击操作
})
按钮类型:
ButtonType.Capsule:胶囊按钮(默认)ButtonType.Normal:矩形按钮ButtonType.Circle:圆形按钮
五、事件处理机制
5.1 onClick点击事件
onClick是最常用的交互事件,当组件被点击时触发。
@Entry
@Component
struct EventExample {
@State message: string = '点击按钮试试';
build() {
Column() {
Text(this.message)
.fontSize(20)
Button('改变文本')
.onClick(() => {
this.message = '文本已改变!';
})
Button('显示坐标')
.onClick((event: ClickEvent) => {
console.log(`点击坐标: (${event.x}, ${event.y})`);
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
事件对象参数:
event.x:点击点相对于被点击元素左边沿的X坐标event.y:点击点相对于被点击元素上边沿的Y坐标event.screenX:点击点相对于设备屏幕左边沿的X坐标event.screenY:点击点相对于设备屏幕上边沿的Y坐标
5.2 事件方法定义方式
方式一:匿名函数(推荐)
Button('按钮')
.onClick(() => {
console.log('按钮被点击');
})
方式二:成员函数
@Component
struct MyComponent {
handleClick = () => {
console.log('按钮被点击');
}
build() {
Button('按钮')
.onClick(this.handleClick)
}
}
方式三:事件传参
@Component
struct MyComponent {
sayHello = (name: string) => {
console.log(`你好, ${name}`);
}
build() {
Button('打招呼')
.onClick(() => {
this.sayHello('张三');
})
}
}
六、综合实战案例
6.1 计数器应用
@Entry
@Component
struct CounterApp {
@State count: number = 0;
build() {
Column({ space: 20 }) {
// 标题
Text('计数器')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor('#333')
// 显示计数
Text(`当前计数: ${this.count}`)
.fontSize(40)
.fontColor('#007DFF')
// 操作按钮
Row({ space: 15 }) {
Button('减少')
.width(100)
.height(50)
.backgroundColor('#FF6B6B')
.fontColor(Color.White)
.onClick(() => {
this.count--;
})
Button('重置')
.width(100)
.height(50)
.backgroundColor('#FFD93D')
.fontColor('#333')
.onClick(() => {
this.count = 0;
})
Button('增加')
.width(100)
.height(50)
.backgroundColor('#6BCB77')
.fontColor(Color.White)
.onClick(() => {
this.count++;
})
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
6.2 图片切换器
@Entry
@Component
struct ImageGallery {
@State currentImage: number = 1;
build() {
Column({ space: 20 }) {
// 显示当前图片
Image($r(`app.media.image${this.currentImage}`))
.width(300)
.height(300)
.objectFit(ImageFit.Cover)
.borderRadius(10)
// 切换按钮
Row({ space: 10 }) {
Button('上一张')
.width(120)
.height(40)
.onClick(() => {
if (this.currentImage > 1) {
this.currentImage--;
}
})
Text(`第 ${this.currentImage} 张`)
.fontSize(16)
.fontColor('#666')
Button('下一张')
.width(120)
.height(40)
.onClick(() => {
if (this.currentImage < 5) {
this.currentImage++;
}
})
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
七、开发注意事项
7.1 状态更新规则
正确方式(创建新对象):
@State user = { name: '张三', age: 25 };
// 正确:创建新对象
this.user = { ...this.user, name: '李四' };
错误方式(直接修改属性):
// 错误:不会触发UI更新
this.user.name = '李四';
7.2 组件命名规范
- 自定义组件名不能与系统组件名相同
- 建议使用大驼峰命名法(如:MyComponent)
- 避免使用保留关键字作为组件名
7.3 样式单位
- vp(Virtual Pixel):虚拟像素,随屏幕密度变化
- fp(Font Pixel):字体像素单位
- px:物理像素,不建议使用(不同设备显示效果不同)
八、总结
通过本篇教程,您已经掌握了:
✅ ArkTS语言的核心特性与声明式UI开发范式
✅ @State装饰器的使用方法与状态管理原理
✅ Text、Image、Button等基础组件的使用
✅ onClick事件处理机制
✅ 综合实战案例开发
关键知识点回顾:
- 声明式开发聚焦于描述UI与数据的映射关系
- @State装饰的变量变化会自动触发UI更新
- 组件通过链式调用配置属性和事件
- 事件处理支持多种定义方式
建议您动手实践文中的案例代码,加深对声明式UI和状态管理的理解。下一篇我们将学习布局系统与组件样式,掌握如何构建复杂的页面布局。
浙公网安备 33010602011771号