用 HML + CSS + JS 三段式写鸿蒙界面
一段式和三段式的区别
声明式范式把所有东西写在一个 .ets 文件里,结构、样式、逻辑混在一起。类 Web 范式回到经典的 Web 三段式:HML 管结构、CSS 管样式、JS 管逻辑,一个页面对应三个文件。
声明式范式:一个文件
page.ets ── 结构 + 样式 + 逻辑
类 Web 范式:三个文件
page.hml ── 结构(标签树)
page.css ── 样式(选择器 + 属性)
page.js ── 逻辑(数据 + 事件处理)
这套写法对 Web 前端开发者几乎零学习成本,迁移已有 Web 应用也快。
一个完整的计数器页面
HML 结构文件
<!-- index.hml -->
<div class="container">
<!-- 文本组件,数据来自 JS 里的 count -->
<text class="count">{{ count }}</text>
<!-- 按钮,点击触发 increase 方法 -->
<button class="btn" onclick="increase">+1</button>
</div>
HML 用标签声明组件,{{ count }} 是数据绑定语法,onclick 绑定事件。
CSS 样式文件
/* index.css */
.container {
flex-direction: column; /* 纵向排列 */
justify-content: center; /* 垂直居中 */
align-items: center; /* 水平居中 */
width: 100%;
height: 100%;
}
.count {
font-size: 48px;
margin-bottom: 24px;
}
.btn {
width: 120px;
height: 48px;
}
CSS 用选择器定位组件再设置样式,和 Web 完全一致。
JS 逻辑文件
// index.js
export default {
data: {
count: 0 // 页面数据,HML 里的 {{ count }} 绑定的就是它
},
increase() {
this.count++; // 修改数据,UI 自动更新
}
}
data 里声明页面数据,方法直接挂载在对象下供 HML 调用。改 this.count 后,绑定处自动刷新,这就是单向数据绑定。
整体架构:四层结构
类 Web 范式的架构和声明式范式不同,它多了一层前台框架:
┌────────────────┐
│ Application │ JS FA 应用(开发者开发的 FA 应用)
├────────────────┤
│ Framework │ 页面解析、MVVM 模式、路由机制、自定义组件
├────────────────┤
│ Engine │ 动画解析、DOM 树构建、布局计算、渲染命令、事件管理
├────────────────┤
│ Porting Layer │ 平台抽象:事件对接、渲染管线、生命周期
└────────────────┘
这里的 Framework 层提供 MVVM(Model-View-ViewModel)开发模式——data 是 Model,HML 是 View,框架负责把两者绑定起来。Engine 层负责构建 DOM 树和布局计算,这正是声明式范式省掉的部分,也是类 Web 范式性能略逊的原因。
ArkUI.Full 和 ArkUI.Lite 怎么选
类 Web 范式内部又分两个版本:
| 版本 | 定位 | 组件能力 | 面向设备 |
|---|---|---|---|
| ArkUI.Full | 完整版 | 完整容器/基础/媒体/画布/栅格/SVG 组件 + 自定义组件 | 手机、平板等 |
| ArkUI.Lite | 轻量版(Full 的子集) | 部分核心容器、基础、基础画布组件 | 运动手表等资源受限设备 |
选 Full 还是 Lite 看设备。面向手表的轻量应用用 Lite,功能复杂交互丰富的应用用 Full。Lite 是 Full 的子集,意味着 Lite 里能写的组件 Full 里都能写。
单向数据绑定的边界
类 Web 范式是"单向数据绑定"——数据变了 UI 更新,但 UI 变化不会自动写回数据。所以输入框这类场景要手动监听:
export default {
data: {
username: ''
},
// 输入框内容变化时回调
onUsernameChange(e) {
this.username = e.value; // 手动把输入同步回数据
}
}
声明式范式里 @State 是双向感知的(数据驱动 UI,事件回调写回数据),类 Web 范式里这个"写回"要自己在事件里做,这就是单向和双向在开发体验上的差别。
什么时候还用类 Web 范式
主推的声明式范式功能更强性能更好,但类 Web 范式没有废弃,适用于:
- Web 开发团队转岗:团队全是 Web 前端,类 Web 范式上手最快
- 迁移已有 Web 应用:HML/CSS/JS 结构接近,改造工作量小
- 简单的中小型应用:界面不复杂,不需要声明式的高级状态管理
- FA 模型卡片:FA 模型的卡片只支持类 Web 范式
除此之外,新项目都建议走声明式。
两条容易忽略的通则
-
this绑定:方法里用this.count访问数据,注意方法被调用时this的指向。用箭头函数或确保方法在 JS 对象下正常绑定。 -
组件属性命名:HML 组件属性不少和 Web 有差异,不能想当然。写之前查一下对应组件的属性文档,别用 Web 的惯性去套。
一点实战体会哦
类 Web 范式适合快速出原型。但你如果打算做长期维护的应用,还是尽早转声明式——数据驱动 UI 的写法在状态多了之后明显更省心,不用在 JS 里手动管理一堆 DOM 更新。两者学了不冲突,搞清楚差异,选型时心里有数就行。
更多推荐


所有评论(0)