在这里插入图片描述

在这里插入图片描述

子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)

大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、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 架构中,这不是“优化建议”,而是:

必须遵守的架构规则

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐