随着HarmonyOS生态的日渐完善,越来越多的厂商加入鸿蒙系统应用开发的行列。然而从其他系统转到鸿蒙开发,很多开发者还是需要一个适应的过程,特别是面对比较复杂的页面,应该如何合理进行模块化拆分是一个难点。
本文将通过一个实例,来分析如果采用模块化的方式实现一个包含丰富内容和交互的复杂页面。
一、复杂页面的痛点
随着智能设备性能的不断提升,我们开发的App页面也日益复杂,包含更多的功能模块和交互需求。直接在一个页面文件中开发所有功能,很容易造成以下问题:
- 代码量庞大,一个文件上千行代码,极其不利于后续维护
- 各模块功能高度耦合,测试和迭代非常不方便
- UI和交互修改会影响到多个模块,冲突概率大
所以我们迫切需要采用模块化的方式来开发复杂页面。
二、页面模块化拆分
1. 复杂页面概览
我们假设需要开发一个旅游摄影社区的 App,其中有一个发帖页面,包含选择图片、拍摄图片、输入标题和正文、添加地点等多个组件,同时页面交互也非常复杂。
先来看下简单的页面结构,页面可以明显划分为多个功能模块:
- 标题输入模块
- 内容输入模块
- 图片模块
- 图片列表
- 拍照或从相册选择
- 地点模块
- 提交按钮
这已经是一个比较复杂的页面了,如果全部写在一个 .hml 文件中,会非常难以维护。
所以我们需要进行模块化拆分。
2.模块化拆分实现
鸿蒙提供了 <import> 和 <include> 标签来进行模块化:
比如我们创建 title-input.hml、content-input.hml等组件文件,然后在页面中导入:
<!-- index.hml -->
<div class="page">
<import src="title-input.hml" />
<import src="content-input.hml" />
<image src=""></image>
<text class="location"></text>
<button type="primary">发布</button>
</div>
这样就实现了模块的解耦。
3. 小组件之间的数据交互
视图拆分完成后,我们还需要thinking数据交互问题。这就需要用到观察者模式。
在JS Ability中我们可以定义观察方法,小组件可以调用这些方法主动通知 Ability 数据变化,完成跨组件的数据流转,比如:
// index.js
export default {
data: {
title: ""
},
updateTitle(newTitle) {
this.title = newTitle;
}
}
// title-input.js
import ability from "../index.js";
function onTitleChange(newTitle) {
ability.updateTitle(newTitle);
}
这样title-input组件就可以通过updateTitle方法来改变index页面的数据。
标题和内容输入组件可以在输入时主动调用这些方法更新ability中保存的数据,这样就实现了跨组件通信。
页面提交按钮的点击事件,也可以直接获取ability上已经更新过的最新数据后处理。
通过以上方法,我们实现了页面的模块化拆分,并处理了组件之间的数据交互问题。这样代码结构清晰,可维护性也大幅提高。
三、页面数据管理
复杂页面中,不同模块都可能改变ABILITY中的数据。为了规范数据流向,我们通常会设置一些数据管理规则:
- 所有页面数据只能通过Ability管理,不能由单个组件自己保存
- 数据更新必须通过Ability暴露出来的方法,不能私自修改其它数据
- 对于不确定的中间状态数据,应封装为JS函数内部变量,不暴露到ABILITY中
按照这些原则,可以保证数据流向清晰,修改 predictable。
四、总结
模块化设计是开发复杂页面的关键。本文通过一个实例,介绍了如何利用鸿蒙的import/include
以及观察者模式实现模块化拆分,并处理好组件间的数据交互问题。
模块化开发能大幅提高代码质量,如果你在鸿蒙应用开发过程中也遇到类似复杂页面的困扰,不妨借鉴本文的解决方案。
欢迎大家在评论区分享你的模块化设计经验!