为什么 HarmonyOS PC 应用离不开文档模型



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

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

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

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

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

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

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

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

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

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

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

持续写作,持续进阶。

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

文章目录

如果你第一次做 HarmonyOS PC 应用,很可能会先从 UI 入手:

  • 页面怎么拆
  • 布局怎么做
  • 多窗口怎么画

这些都没错,但几乎一定会走弯路

因为在 PC 世界里,有一个东西比 UI 更早、也更重要:

文档模型(Document Model)。

什么叫"文档模型"?先别想得太复杂

这里说的"文档",不一定是 Word 那种文件。

它更接近的是:

一个可长期存在、
可被操作、
可被保存 / 恢复的核心对象。

比如:

  • 编辑器里的文件
  • 设计工具里的工程
  • 表格应用里的数据集
  • IDE 里的 Project

本质都是:

ts 复制代码
class Document {
  id: string
  path?: string
  dirty: boolean
  content: any
}

这才是 PC 应用真正"活着"的东西。

App 思维:页面是中心

很多团队一开始会这么写:

ts 复制代码
@Component
struct EditorPage {
  @State content: string = ''
}

页面存在,内容存在;

页面销毁,内容就没了。

在 App 里,这很常见。但在 PC 应用里,这几乎一定会出事。

PC 世界的第一个现实需求:多窗口编辑

当用户说:

"我想同时打开两个文件。"

你会开始这样改:

ts 复制代码
@State editors: EditorState[] = []
ts 复制代码
interface EditorState {
  path: string
  content: string
}

短期内能跑,但很快你会发现问题:

  • 窗口之间怎么共享?
  • 同一个文档被打开两次怎么办?
  • 关闭一个窗口,是不是就该销毁内容?

你其实已经在被迫设计文档模型了,只是方式非常被动。

正确的顺序,应该是反过来的

成熟的 PC 应用,顺序通常是:

  1. 先定义 Document
  2. 再定义 Document 生命周期
  3. 最后才是 窗口和 UI 绑定

一个最小但正确的起点

ts 复制代码
class Document {
  id: string
  path?: string
  content: string
  dirty: boolean = false
}
ts 复制代码
class DocumentManager {
  private docs = new Map<string, Document>()

  open(path: string): Document
  close(doc: Document)
  save(doc: Document)
}

UI 从一开始就只是"观察者"。

文档模型,解决的是"谁拥有状态"的问题

错误归属

text 复制代码
窗口 → 内容

正确归属

text 复制代码
文档 → 内容
窗口 → 视图

代码差异非常明显。

错误写法

ts 复制代码
@Component
struct EditorWindow {
  @State content: string
}

正确写法

ts 复制代码
@Component
struct EditorWindow {
  doc: Document
}
ts 复制代码
TextArea({ text: doc.content })

没有文档模型,Undo / Redo 几乎一定会失败

这是很多团队"后期才发现"的坑,如果你的状态散落在 UI 里:

ts 复制代码
@State text: string
@State cursor: number

Undo 很快就会变成:

  • 只回滚一部分
  • 顺序混乱
  • 窗口之间不同步

而有了文档模型,你可以直接:

ts 复制代码
class Document {
  history: Command[]
}
ts 复制代码
undo() {
  history.pop().rollback(this)
}

自动保存、崩溃恢复,全部依赖文档模型

PC 应用默认假设:

进程可能随时死。

这意味着:

  • 自动保存
  • 会话恢复
  • 崩溃后重开

都必须是系统能力级别

ts 复制代码
serialize(doc): Snapshot
restore(snapshot): Document

如果这些逻辑写在页面里,你根本无法统一处理。

多窗口 + 一个文档,是 PC 应用的常态

再看一个常见场景:

同一个文档

同时在两个窗口里打开

如果没有文档模型,你会遇到:

  • 内容不同步
  • 保存冲突
  • 状态不可预期

有了文档模型,结构会非常清晰:

ts 复制代码
doc = documentManager.open(path)

windowA.bind(doc)
windowB.bind(doc)

UI 只是不同视角。

HarmonyOS PC 应用,为什么"尤其需要"文档模型?

因为 HarmonyOS 给你的能力是:

  • 多窗口
  • 多任务
  • 长时间运行
  • 系统级文件访问

但它不会替你解决:

状态该放哪儿。

如果你不先设计文档模型,后面所有能力都会变成负担。

一个现实的判断标准

你可以用一个问题自检:

如果我现在关掉所有窗口,
这个应用的"核心状态"还在吗?

  • 如果答案是"在"------
    你大概率走在正确的 PC 路上
  • 如果答案是"不在"------
    你还在用 App 思维写 PC

总结

为什么 HarmonyOS PC 应用,必须先设计文档模型?

因为在 PC 世界里:

  • 窗口是暂时的
  • 页面是可替换的
  • UI 是表现层

而真正长期存在的,只有:

文档、会话、任务、状态。

如果你先设计 UI,文档模型迟早会反过来逼你重构。

但如果你一开始就把文档模型立住:

UI 会变得很轻

多窗口会变得自然

生命周期问题会自动消失一半

相关推荐
小镇敲码人4 小时前
华为CANN框架中HCCL仓库的全面解析:分布式通信的引擎
分布式·华为
王码码20354 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
坚果派·白晓明5 小时前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人5 小时前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
lbb 小魔仙5 小时前
【HarmonyOS实战】OpenHarmony + RN:自定义 useFormik 表单处理
react native·harmonyos
果粒蹬i5 小时前
【HarmonyOS】DAY7:鸿蒙跨平台 Tab 开发问题与列表操作难点深度复盘
华为·harmonyos
程序员agions6 小时前
2026年,微前端终于“死“了
前端·状态模式
王码码20356 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
小镇敲码人6 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn
ITUnicorn6 小时前
【HarmonyOS6】ArkTS 自定义组件封装实战:动画水杯组件
华为·harmonyos·arkts·鸿蒙·harmonyos6