第10章_HarmonyOs开发图解 用JS开发UI
第10章 HarmonyOs开发图解 用 JS 开发 UI
HarmonyOS 学习系统 | 阶段二:进阶实战期
建议学习时长:2-3 周
学习目标
| 序号 | 能力 |
|---|---|
| 1 | 理解 JS UI 声明式编程模型和 MVVM 架构 |
| 2 | 掌握 hml/css/js 三件套的开发流程 |
| 3 | 能实现数据绑定和事件处理 |
| 4 | 了解 JS FA 调用 Java PA 的两种方式 |
核心图解

内容讲解
10.1 JS UI 概述
如果你有网页开发经验,JS UI 会让你感到非常亲切:
- .hml 文件 = HTML 文件——定义页面结构(但叫 hml 不是 html)
- .css 文件 = CSS 文件——定义页面样式(跟 CSS 几乎一样)
- .js 文件 = JavaScript 文件——定义业务逻辑(标准 ECMAScript)
- AceAbility = Java FA 的 JS 版本——JS 页面的宿主
- 数据绑定 {{ }} = Vue.js 的模板语法——变量变了界面自动更新
JS UI 的基础能力
| 能力 | 说明 |
|---|---|
| 声明式编程 | 类 HTML 和 CSS 声明式语言,避免编写 UI 状态切换代码 |
| 跨设备 | 运行时自动映射到不同设备类型,开发者无感知 |
| 高性能 | 针对声明式语法进行了渲染流程优化 |
JS UI 框架架构
JS UI 框架分为四层:
- 应用层 (Application Layer):开发者使用 JS UI 框架开发的 FA 应用
- 前端框架层 (Framework Layer):MVVM 开发模式、页面路由机制、自定义组件
- 引擎层 (Engine Layer):DOM 树构建、布局计算、渲染命令构建、事件管理
- 平台适配层 (Porting Layer):抽象接口,对接到系统平台
基准宽度
- 手机和智慧屏:以 720px(逻辑像素)为基准宽度
- 智能穿戴设备:以 454px 为基准宽度
- 实际显示时会根据屏幕物理像素自动缩放
10.2 JS FA 开发
创建 JS FA 应用
创建工程时选择 Empty Ability(JS) 模板。JS FA 通过 AceAbility 类加载,在 config.json 中配置 js 字段指定页面路由。
"js": {
"name": "default",
"pages": [
"pages/index/index"
]
}
AceAbility
AceAbility 是 JS FA 在 HarmonyOS 上运行环境的基类,继承自 Ability。默认代码:
public class MainAbility extends AceAbility {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
}
}
如果修改了 config.json 中的 js.name,需要在 onStart() 中调用 setInstanceName():
@Override
public void onStart(Intent intent) {
super.setInstanceName("JSComponentName");
super.onStart(intent);
}
JS FA 开发目录结构
main/js/default/
├── i18n/ # 国际化
│ ├── en-US.json
│ └── zh-CN.json
├── common/ # 公共资源
│ └── images/
└── pages/
└── index/
├── index.hml # 页面结构
├── index.css # 页面样式
└── index.js # 业务逻辑
三件套详解
index.hml(页面结构):
<div class="container">
<text class="title">{{ title }}</text>
<image src="{{ isPressed ? $r('app.media.liked') : $r('app.media.unliked') }}"
class="like-img" onclick="toggleLike"></image>
<text class="count">{{ count }}</text>
</div>
index.css(页面样式):
.container {
flex-direction: column;
align-items: center;
justify-content: center;
}
.title {
font-size: 30px;
color: #333333;
margin-bottom: 20px;
}
.like-img {
width: 100px;
height: 100px;
}
.count {
font-size: 24px;
color: #e91e63;
margin-top: 10px;
}
index.js(业务逻辑):
export default {
data: {
title: 'Hello HarmonyOS!',
isPressed: false,
count: 99
},
toggleLike() {
this.isPressed = !this.isPressed;
if (this.isPressed) {
this.count++;
} else {
this.count--;
}
}
}
数据绑定机制:JS UI 采用 MVVM 模式,data 中的变量通过 {{ 变量名 }} 绑定到视图。当变量值发生变化时,视图自动更新——这和 Vue.js 的响应式原理类似。
10.3 JS UI 组件与布局
组件分类
| 分类 | 组件 |
|---|---|
| 基础组件 | text、image、progress、rating、span、marquee、divider、search |
| 容器组件 | div、list、list-item、stack、swiper、tabs、tab-bar、tab-content、refresh |
| 媒体组件 | video |
| 画布组件 | canvas |
常用布局 CSS 属性
| 属性 | 说明 | 示例值 |
|---|---|---|
flex-direction |
排列方向 | column / row |
justify-content |
主轴对齐 | center / flex-start / flex-end / space-between |
align-items |
交叉轴对齐 | center / flex-start / flex-end / stretch |
flex-wrap |
是否换行 | wrap / nowrap |
flex-weight |
权重(占比) | 1 / 2 / 3 |
10.4 JS FA 调用 PA
JS UI 框架提供了 JS FA 调用 Java PA 的机制,支持两种调用方式:
| 方式 | 生命周期 | 通信方式 | 适用场景 |
|---|---|---|---|
| Ability | 独立 Ability 生命周期 | 远程进程通信 (RPC) | 多 FA 调用、后台独立运行 |
| Internal Ability | 与 FA 共进程 | 内部函数调用 | 对时延要求高的场景 |
JS 端调用 PA
import FeatureAbility from '@ohos.featureability';
export default {
data: {
result: '等待计算结果...'
},
play() {
FeatureAbility.callAbility({
bundleName: 'com.example.jsfacallpa',
abilityName: 'PlayAbility',
messageCode: 1001,
data: { numbers: [1, 2, 3, 4, 5] },
arity: 1
}).then((data) => {
this.result = '计算结果: ' + data.result;
}).catch((error) => {
this.result = '调用失败: ' + error;
});
}
}
Java PA 端处理
public class PlayAbility extends Ability {
@Override
public boolean onRemoteRequest(int code, MessageParcel data,
MessageParcel reply, MessageOption option) {
if (code == 1001) {
// 解析参数
String numbersStr = data.readString();
// 执行计算
int sum = 0;
// ... 计算逻辑
reply.writeString(String.valueOf(sum));
return true;
}
return false;
}
}
代码速查卡
| 特性 | Java UI | JS UI |
|---|---|---|
| 编程范式 | 命令式 | 声明式 (MVVM) |
| 布局定义 | XML 文件 | HML 文件 |
| 样式定义 | XML 属性 / graphic XML | CSS 文件 |
| 数据绑定 | 手动 findComponentById + setText | 自动 {{ 变量名 }} |
| 宿主类 | Ability extends Ability |
AceAbility extends Ability |
| 页面单元 | AbilitySlice | .hml + .css + .js 三件套 |
| 适合人群 | Java/Android 开发者 | 前端/Web 开发者 |
| 跨设备适配 | 需手动适配 | 自动适配(720px 基准) |
| 事件绑定 | setClickedListener() |
onclick="methodName" |
| 调用 PA | 直接 Java 调用 | FeatureAbility.callAbility() |
与 Android/iOS 对比
| 特性 | HarmonyOS JS UI | Android (Jetpack Compose) | iOS (SwiftUI) |
|---|---|---|---|
| 编程语言 | JavaScript | Kotlin | Swift |
| 编程范式 | 声明式 MVVM | 声明式 | 声明式 |
| 模板语法 | hml (类 HTML) | @Composable 函数 | @ViewBuilder |
| 样式定义 | CSS 文件 | Modifier 链式调用 | 修饰符链式调用 |
| 数据绑定 | {{ }} 自动 | remember / state | @State / @Binding |
| 跨平台 | HarmonyOS 多设备 | Android 设备 | Apple 设备 |
⚠️ 踩坑回忆录
第一次写 JS FA 时,我直接把 HTML 语法搬过来了,写了 <div class="box" style="color:red">,结果样式完全没生效。后来才明白 hml 语法虽然类似 HTML 但不完全一样,内联样式要用 style 属性但语法有差异,而且有些 HTML 标签在 hml 中是不支持的。
另外,JS FA 的运行时和 Java FA 不同——Java FA 运行在方舟运行时上,JS FA 运行在 JS 引擎上,两者的生命周期管理也不一样,不能混用。如果你在 JS FA 中需要调用 Java 的能力,必须通过 FA 调用 PA 的机制来桥接。
必做实操任务
| 序号 | 任务 | 难度 |
|---|---|---|
| 1 | 使用 Empty Ability(JS) 模板创建应用并运行 | ★☆☆ |
| 2 | 实现点赞按钮功能(数据绑定 + 事件处理) | ★★☆ |
| 3 | 使用 list 组件实现一个简单的列表展示 | ★★☆ |
| 4 | 使用 tabs 组件实现多 Tab 页面切换 | ★★☆ |
| 5 | 实现 JS FA 调用 Java PA 的计算功能 | ★★★ |
学习检查清单
- 能说出 JS UI 框架的四层架构
- 能创建 JS FA 工程并理解目录结构
- 能实现数据绑定({{ }} 语法)
- 能实现事件处理(onclick 等事件)
- 能说出 hml/css/js 三件套各自的职责
- 能解释 MVVM 模式在 JS UI 中的应用
- 能实现 JS FA 调用 PA 的基本流程
- 理解 Java UI 和 JS UI 的核心区别
阶段二学习路径

进阶方向
- 深入学习 JS UI 的自定义组件开发
- 学习 swiper、refresh 等高级容器组件
- 了解 JS UI 的页面路由(router)机制
- 学习响应式布局和自适应屏幕
更多推荐



所有评论(0)