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 → 行为一定散
相关推荐
●VON4 小时前
HarmonyOS应用开发实战(基础篇)Day09-《构建布局详解下》
华为·harmonyos·训练营·von
●VON4 小时前
HarmonyOS应用开发实战(基础篇)Day08-《构建布局详解上》
华为·harmonyos·鸿蒙·von
键盘鼓手苏苏16 小时前
Flutter for OpenHarmony:csslib 强力 CSS 样式解析器,构建自定义渲染引擎的基石(Dart 官方解析库) 深度解析与鸿蒙适配指南
css·flutter·harmonyos
阿林来了1 天前
Flutter三方库适配OpenHarmony【flutter_speech】— 持续语音识别与长录音
flutter·语音识别·harmonyos
松叶似针1 天前
Flutter三方库适配OpenHarmony【secure_application】— 与 HarmonyOS 安全能力的深度集成
安全·flutter·harmonyos
星空22231 天前
【HarmonyOS】day39:React Native实战项目+智能文本省略Hook开发
react native·华为·harmonyos
山北雨夜漫步1 天前
点评Day06 剩下的卡拉米,我不都写,只写一些新奇的
状态模式
星空22231 天前
【HarmonyOS】day40:React Native实战项目+自定义Hooks开发指南
react native·华为·harmonyos
Swift社区2 天前
鸿蒙 PC 架构的终点:工作流
华为·harmonyos
左手厨刀右手茼蒿2 天前
Flutter for OpenHarmony:dart_console 打造炫酷命令行界面,绘制表格、控制光标与进度条(CLI 交互库) 深度解析与鸿蒙适配指南
flutter·交互·harmonyos·绘制