第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 字段指定页面路由。
json
"js": {
"name": "default",
"pages": [
"pages/index/index"
]
}
AceAbility
AceAbility 是 JS FA 在 HarmonyOS 上运行环境的基类,继承自 Ability。默认代码:
java
public class MainAbility extends AceAbility {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
}
}
如果修改了 config.json 中的 js.name,需要在 onStart() 中调用 setInstanceName():
java
@Override
public void onStart(Intent intent) {
super.setInstanceName("JSComponentName");
super.onStart(intent);
}
JS FA 开发目录结构
bash
main/js/default/
├── i18n/ # 国际化
│ ├── en-US.json
│ └── zh-CN.json
├── common/ # 公共资源
│ └── images/
└── pages/
└── index/
├── index.hml # 页面结构
├── index.css # 页面样式
└── index.js # 业务逻辑
三件套详解
index.hml(页面结构):
html
<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(页面样式):
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(业务逻辑):
javascript
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
javascript
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 端处理
java
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)机制
- 学习响应式布局和自适应屏幕