用 HML + CSS + JS 三段式写鸿蒙界面

一段式和三段式的区别

声明式范式把所有东西写在一个 .ets 文件里,结构、样式、逻辑混在一起。类 Web 范式回到经典的 Web 三段式:HML 管结构、CSS 管样式、JS 管逻辑,一个页面对应三个文件。

复制代码
声明式范式:一个文件
  page.ets ── 结构 + 样式 + 逻辑

类 Web 范式:三个文件
  page.hml ── 结构(标签树)
  page.css ── 样式(选择器 + 属性)
  page.js  ── 逻辑(数据 + 事件处理)

这套写法对 Web 前端开发者几乎零学习成本,迁移已有 Web 应用也快。

一个完整的计数器页面

HML 结构文件

html 复制代码
<!-- 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 样式文件

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 逻辑文件

javascript 复制代码
// 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 变化不会自动写回数据。所以输入框这类场景要手动监听:

javascript 复制代码
export default {
  data: {
    username: ''
  },

  // 输入框内容变化时回调
  onUsernameChange(e) {
    this.username = e.value;  // 手动把输入同步回数据
  }
}

声明式范式里 @State 是双向感知的(数据驱动 UI,事件回调写回数据),类 Web 范式里这个"写回"要自己在事件里做,这就是单向和双向在开发体验上的差别。

什么时候还用类 Web 范式

主推的声明式范式功能更强性能更好,但类 Web 范式没有废弃,适用于:

  1. Web 开发团队转岗:团队全是 Web 前端,类 Web 范式上手最快
  2. 迁移已有 Web 应用:HML/CSS/JS 结构接近,改造工作量小
  3. 简单的中小型应用:界面不复杂,不需要声明式的高级状态管理
  4. FA 模型卡片:FA 模型的卡片只支持类 Web 范式

除此之外,新项目都建议走声明式。

两条容易忽略的通则

  1. this 绑定 :方法里用 this.count 访问数据,注意方法被调用时 this 的指向。用箭头函数或确保方法在 JS 对象下正常绑定。

  2. 组件属性命名:HML 组件属性不少和 Web 有差异,不能想当然。写之前查一下对应组件的属性文档,别用 Web 的惯性去套。

一点实战体会哦

类 Web 范式适合快速出原型。但你如果打算做长期维护的应用,还是尽早转声明式------数据驱动 UI 的写法在状态多了之后明显更省心,不用在 JS 里手动管理一堆 DOM 更新。两者学了不冲突,搞清楚差异,选型时心里有数就行。

相关推荐
非优秀程序员7 小时前
第07章 孙德良的阳谋|《互联网产品恩仇录》
javascript·后端
程序员大阳11 小时前
HTML+CSS+JS对话式实战(5)-活动管理页之查看报名名单的实现
javascript·css·html·查看报名名单
曦樂~11 小时前
【Web Development】02 CSS
前端·css
贾伟康11 小时前
HarmonyOS API 26 DevEco Code 需求到 ArkTS 骨架的提示词分层
harmonyos·arkts·ai coding·deveco code·工程提效
东鹏特饮11 小时前
经典打砖块(Breakout)游戏
前端·css·css3
威哥爱编程12 小时前
模拟面试智能体开发实战 02:回答等半分钟,谁还愿意练?把服务端和流式输出搭起来
python·agent·harmonyos
威哥爱编程12 小时前
模拟面试智能体开发实战 01:面试挂了都不知道挂在哪?用 Python 给自己造一个随叫随到的 AI 面试官
python·agent·harmonyos
新*13 小时前
从一段 WebSocket 代码聊开:bytes 不是 zlib、binaryType 决定一切,15MB 大消息的零拷贝优化
javascript·python·websocket·性能优化·blob·zlib·arraybuffer
OpsEye14 小时前
别再挨个充会员了:多模型编码,最麻烦的从来不是选模型
javascript·ai编程
学以智用16 小时前
jsencrypt.js 完整详解
javascript