HarmonyOS PC 文档模型完整范式



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

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

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,

在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。

技术方向: 前端 / 跨端 / 小程序 / 移动端工程化 内容平台: 掘金、知乎、CSDN、简书 创作特点: 实战导向、源码拆解、少空谈多落地 **文章状态:**长期稳定更新,大量原创输出

我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在"API 怎么用",而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。

子玥酱 · 前端成长记录官 ✨

👋 如果你正在做前端,或准备长期走前端这条路

📚 关注我,第一时间获取前端行业趋势与实践总结

🎁 可领取 11 类前端进阶学习资源 (工程化 / 框架 / 跨端 / 面试 / 架构)

💡 一起把技术学"明白",也用"到位"

持续写作,持续进阶。

愿我们都能在代码和生活里,走得更稳一点 🌱

文章目录

    • 引言
    • [一、先划清三层:不要一开始就写 UI](#一、先划清三层:不要一开始就写 UI)
    • 二、文档模型:不是数据,而是"状态载体"
    • [三、Workspace:PC 世界的真正核心](#三、Workspace:PC 世界的真正核心)
      • [Workspace 管什么?](#Workspace 管什么?)
      • [一个最小可用的 Workspace 模型](#一个最小可用的 Workspace 模型)
    • [四、Controller:把"操作流程"从 UI 中拔出来](#四、Controller:把“操作流程”从 UI 中拔出来)
      • [错误:UI 直接 orchestrate 一切](#错误:UI 直接 orchestrate 一切)
      • [正确:引入 WorkspaceController](#正确:引入 WorkspaceController)
    • [五、UI:只是"视图 + 事件映射"](#五、UI:只是“视图 + 事件映射”)
    • [六、为什么这套模型特别适合 PC?](#六、为什么这套模型特别适合 PC?)
    • 七、一个现实世界的对照
    • 总结

引言

PC 形态下,页面不是核心,文档才是。

那接下来真正的问题只有一个:

文档模型,到底该怎么设计,才能撑住多窗口、状态一致性和长期演进?

一、先划清三层:不要一开始就写 UI

一个标准的 HarmonyOS PC 文档模型,至少拆成三层:

复制代码
┌──────────────────┐
│ UI(窗口 / 页面) │
└────────▲─────────┘
         │ 订阅
┌────────┴─────────┐
│ 形态模型层        │  ← PC 专属
│ Workspace / Doc  │
└────────▲─────────┘
         │ 调用
┌────────┴─────────┐
│ 共用能力层        │
│ Repository / IO  │
└──────────────────┘

注意顺序:

  • UI 最后写
  • 模型先稳定
  • 能力层完全不关心形态

二、文档模型:不是数据,而是"状态载体"

错误理解:文档 = 一段内容

ts 复制代码
interface Document {
  id: string
  content: string
}

这只能算存储结构,不算模型。

正确做法:文档是一个"运行态对象"

ts 复制代码
// pc/model/DocumentModel.ts
export class DocumentModel {
  readonly id: string
  content: string

  isDirty: boolean = false
  lastFocusedAt: number = Date.now()

  constructor(doc: Document) {
    this.id = doc.id
    this.content = doc.content
  }

  updateContent(newContent: string) {
    this.content = newContent
    this.isDirty = true
  }
}

这里开始出现关键差异:

  • 文档有 生命周期
  • 文档知道自己"是否被修改"
  • UI 不再自己维护脏状态

三、Workspace:PC 世界的真正核心

如果只记住一句话,那就是:

PC 应用里,Workspace 才是根对象。

Workspace 管什么?

  • 当前打开了哪些文档
  • 文档之间的关系
  • 应用级行为(保存、关闭、恢复)

一个最小可用的 Workspace 模型

ts 复制代码
// pc/model/WorkspaceModel.ts
export class WorkspaceModel {
  private documents = new Map<string, DocumentModel>()

  open(doc: Document) {
    if (!this.documents.has(doc.id)) {
      this.documents.set(doc.id, new DocumentModel(doc))
    }
  }

  close(docId: string) {
    this.documents.delete(docId)
  }

  list(): DocumentModel[] {
    return [...this.documents.values()]
  }

  hasDirtyDocument(): boolean {
    return this.list().some(d => d.isDirty)
  }
}

这里有一个非常重要的工程价值

Workspace 是唯一知道"当前应用状态"的地方。

UI 不需要猜,Service 不需要猜。

四、Controller:把"操作流程"从 UI 中拔出来

错误:UI 直接 orchestrate 一切

ts 复制代码
onCloseApp() {
  if (doc.isDirty) {
    save()
  }
  exit()
}

这种代码一旦出现:

  • 自动保存
  • 批量关闭
  • 崩溃恢复

全都没法统一。

正确:引入 WorkspaceController

ts 复制代码
// pc/controller/WorkspaceController.ts
export class WorkspaceController {
  constructor(
    private workspace: WorkspaceModel,
    private repo: DocumentRepository
  ) {}

  saveAll() {
    for (const doc of this.workspace.list()) {
      if (doc.isDirty) {
        this.repo.save({
          id: doc.id,
          content: doc.content
        })
        doc.isDirty = false
      }
    }
  }

  canExit(): boolean {
    return !this.workspace.hasDirtyDocument()
  }
}

现在:

  • UI 只发意图
  • Controller 统一流程
  • 模型是状态来源

五、UI:只是"视图 + 事件映射"

到这一步,UI 会变得异常干净。

ts 复制代码
// EditorWindow.ets
@State docModel!: DocumentModel

build() {
  TextArea({
    text: this.docModel.content
  })
  .onChange(v => this.docModel.updateContent(v))
}

你会发现:

  • UI 不保存任何业务状态
  • 没有保存逻辑
  • 没有生命周期判断

UI 只是模型的一个投影。

六、为什么这套模型特别适合 PC?

因为它天然支持:

  • 多窗口
  • 多文档
  • 后台保存
  • 崩溃恢复
  • 文档级权限控制

而且每一个能力都有清晰落点

能力 归属
是否修改 DocumentModel
当前打开文档 Workspace
保存策略 Controller
展示 UI

七、一个现实世界的对照

如果你做过这些产品:

  • VS Code
  • Photoshop
  • Keynote
  • Xcode

你会发现它们无一不是文档模型驱动。HarmonyOS PC 只是终于走到了同一个阶段。

总结

HarmonyOS PC 应用的复杂度,不来自窗口多,而来自你有没有一个能承载复杂度的模型。

  • 没有文档模型 → 状态迟早进 UI
  • 没有 Workspace → 多窗口一定崩
  • 没有 Controller → 行为一定散
相关推荐
ITUnicorn3 小时前
【HarmonyOS6】从零实现自定义计时器:掌握TextTimer组件与计时控制
华为·harmonyos·arkts·鸿蒙·harmonyos6
摘星编程3 小时前
OpenHarmony + RN:Stack堆栈导航转场
react native·react.js·harmonyos
BlackWolfSky3 小时前
鸿蒙中级课程笔记13—应用/元服务上架
笔记·华为·harmonyos
财经三剑客5 小时前
鸿蒙智行1月交付57915台,同比增长65.6%
华为·harmonyos
BlackWolfSky6 小时前
鸿蒙中级课程笔记12—应用质量建议与测试指南
笔记·华为·harmonyos
小哥Mark6 小时前
各种Flutter拖拽交互组件助力鸿蒙应用个性化
flutter·交互·harmonyos
听麟6 小时前
HarmonyOS 6.0+ PC端多人联机游戏开发实战:Game Service Kit深度集成与跨设备性能优化
游戏·华为·性能优化·架构·harmonyos·ai-native
森之鸟6 小时前
鸿蒙CoreSpeechKit语音识别实战:让APP“听懂”用户说话
语音识别·xcode·harmonyos
听麟6 小时前
HarmonyOS 6.0+ 个性化音乐播放器APP开发实战:音频可视化与场景化推荐落地
华为·音视频·harmonyos