鸿蒙游戏如何避免“巨型页面文件”?
本文针对鸿蒙开发中常见的"巨型页面文件"问题,提出了一套完整的架构拆分方案。作者指出,当页面混杂UI、逻辑、状态和网络请求时,会导致代码膨胀至数千行难以维护。解决方案遵循"页面只负责UI"原则,将职责拆分为Service(逻辑)、Store(状态)、Component(UI组件)和Network(网络)四个层级,并推荐按业务模块组织代码。最终理想页面应仅包含


大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。
我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。
技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:掘金、知乎、CSDN、简书
创作特点:实战导向、源码拆解、少空谈多落地
文章状态:长期稳定更新,大量原创输出
我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。
子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”
持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱
文章目录
引言
如果你写过一段时间鸿蒙游戏,很可能已经遇到这个问题:
一个页面文件,越来越大。
最开始:
200 行
后来变成:
800 行
再后来:
2000 行 +
而且你会发现:
- UI 写在一起
- 逻辑写在一起
- 网络写在一起
- 状态也写在一起
最后变成一个典型的:
“巨型页面文件(God Component)”
在 HarmonyOS 的 ArkUI 体系下,这个问题尤其常见。
一、为什么会出现“巨型页面”?
核心原因:职责没有拆分
一个典型错误页面:
@Entry
@Component
struct GamePage {
@State score: number = 0
@State list: any[] = []
aboutToAppear() {
this.loadData()
}
async loadData() {
const res = await fetch("/api/list")
this.list = await res.json()
}
movePlayer() {
this.score += 1
}
build() {
Column() {
Text(`Score: ${this.score}`)
Button("移动")
.onClick(() => this.movePlayer())
ForEach(this.list, item => {
Text(item.name)
})
}
}
}
看起来没问题,但其实混在一起了:
UI
状态
网络
逻辑
一旦变复杂:
你会完全失控
二、正确拆分思路
一句话原则:
页面只负责 UI,其它全部拆出去
正确结构:
Page(UI)
↓
Service(逻辑)
↓
Store(状态)
↓
Network(数据)
再加:
Component(UI拆分)
Agent(AI)
三、第一步:拆 Service
页面写逻辑
movePlayer() {
this.score += 1
}
提取到 Service
// services/GameService.ets
import { gameStore } from '../store/GameStore'
export class GameService {
movePlayer() {
gameStore.dispatch({
type: 'ADD_SCORE',
payload: 1
})
}
}
export const gameService = new GameService()
页面变成:
Button("移动")
.onClick(() => gameService.movePlayer())
页面瞬间变干净。
四、第二步:拆 Store
页面管理状态
@State score: number = 0
统一 Store
// store/GameStore.ets
export class GameStore {
state = {
score: 0
}
dispatch(action) {
if (action.type === 'ADD_SCORE') {
this.state.score += action.payload
}
}
}
export const gameStore = new GameStore()
页面只读:
@State state = gameStore.state
页面不再“拥有状态”。
五、第三步:拆组件
页面 UI 堆积
Column() {
Text("玩家")
Image("avatar.png")
Text("分数")
}
拆组件
// components/PlayerInfo.ets
@Component
export struct PlayerInfo {
@Prop score: number
build() {
Column() {
Text("玩家")
Text(`分数:${this.score}`)
}
}
}
页面使用:
PlayerInfo({ score: this.state.score })
页面只负责“拼装 UI”。
六、第四步:拆网络
页面直接 fetch
await fetch("/api/list")
Service 调用
await dataService.fetchList()
页面完全不关心数据来源。
七、第五步:引入模块化
当游戏变大:
推荐结构
modules
├─ player
│ ├─ PlayerService
│ ├─ PlayerStore
│ └─ PlayerComponent
│
├─ task
├─ battle
原则:
按业务拆,而不是按技术层拆
八、最终页面应该长什么样?
理想页面
@Entry
@Component
struct GamePage {
@State state = gameStore.state
build() {
Column() {
PlayerInfo({ score: this.state.score })
Button("移动")
.onClick(() => gameService.movePlayer())
}
}
}
页面只剩:
UI + 事件绑定
这才是正确形态。
九、判断标准
如果你的页面:
出现这些
- 有 fetch
- 有复杂逻辑
- 有多层 if
- 有状态计算
说明已经“变胖了”。
正确状态
页面应该:
简单到可以一眼看懂
十、为什么这很重要?
1、可维护性
逻辑在 Service
状态在 Store
修改不会影响 UI。
2、可扩展性
你可以轻松加:
- AI
- 多端
- 网络
3、团队协作
UI开发
逻辑开发
AI开发
可以分开做。
4、避免“技术债”
巨型页面的本质是:
技术债爆炸前兆
总结
避免“巨型页面文件”的核心方法:
1、逻辑进 Service
2、状态进 Store
3、UI 拆 Component
4、网络独立
5、按模块拆分
在 HarmonyOS 的 ArkUI 架构中,这不是“优化建议”,而是:
必须遵守的架构规则
更多推荐


所有评论(0)