鸿蒙 PC Markdown 编辑器标签系统十二标签上限与桌面交互标签栏是多文档状态的可视投影。它要表达活动文档、文件名、未保存状态、关闭动作和新建入口还要在自由窗口缩窄时保持可操作。无限标签看似自由实际会让完整 EditorState、撤销历史和正文无界驻留内存。本文基于 OhMarkdown分析十二标签上限、URI去重、空白会话复用、稳定身份、活动标签切换和关闭后继。代码位于 https://gitcode.com/VON-/codex_md_oh对应提交3a9146e。上限是内存策略exportconstMAX_OPEN_DOCUMENT_SESSIONS12;每个 Web会话保存 CodeMirror EditorState、正文树、选区和撤销历史原生会话还保存正文、持久化基线、格式与状态。标签不是只有几十字节标题。当前没有后台冻结和历史压缩所以十二是明确保护边界。达到上限时拒绝创建并显示if(this.documentSessions.lengthMAX_OPEN_DOCUMENT_SESSIONS){this.operationStatusOpen document limit reached (${MAX_OPEN_DOCUMENT_SESSIONS});return;}拒绝发生在修改数组之前不创建半会话。打开文件路径也检查并抛出明确错误。未来提高上限应先测总内容和历史内存而不是只改常量。sessionId 是标签身份新会话 id由单调序列产生privatecreateDocumentSessionId():string{this.documentSessionSequence1;returndocument-session-${this.documentSessionSequence};}文件名不能作为 key多个 Untitled同名URI不能覆盖未命名数组索引在关闭和插入后变化。sessionId只在进程内唯一足够对齐 ArkUI ForEach与 Web Map。标签渲染 keyForEach(this.documentSessions,(session:DocumentSession){this.documentTab(session)},(session:DocumentSession):stringsession.id)稳定 key避免关闭左侧标签后框架把右侧组件状态错误复用到新索引。新建前捕获当前正文awaitthis.captureActiveDocumentSession();constsessioncreateUntitledSession(this.createDocumentSessionId());this.documentSessionsthis.documentSessions.concat([session]);this.applyDocumentSession(session);this.setEditorDocument();先从 ArkWeb读取当前全文并同步旧会话再追加新项。若先切 active id捕获内容会写进空会话。数组使用 concat产生新引用触发 ArkUI更新。新文档拥有默认 UTF-8无 BOM、LF、revision 0和 dirty false。它不是复用上一标签页面字段后只清空正文否则格式和状态会泄漏。打开文件先按 URI 去重constopenedSessionthis.documentSessions.find((session)session.uriopenedDocument.uri);if(openedSession){awaitthis.captureActiveDocumentSession();this.applyDocumentSession(openedSession);awaitthis.activateEditorSession(openedSession);return;}文件树重复点击同一 URI只激活已有标签。若创建两个副本两个脏缓冲区覆盖同一外部文件会产生不可解释冲突。URI去重是保存安全的一部分。URI比较依赖系统返回值规范。不同 provider若给同一文件不同 URI需要未来引入文档标识或规范化当前不通过字符串 path猜测身份。首次打开复用干净空白标签constcanReuseActiveSessionactiveSession!undefinedactiveSession.uri.length0!activeSession.dirtyactiveSession.content.length0;应用启动自带一个空标签。第一次打开文件时复用避免留下无意义 Untitled。三个条件缺一不可无 URI、未修改、正文为空。已经保存但内容为空的真实文件有 URI不能被复用未命名但脏的空内容可能经历输入再删除仍需保留其历史与恢复语义。复用时保持 sessionId替换会话对象否则追加新 id。Web使用setSessionDocument删除该 id旧快照并重建确保撤销历史不会回到空白标签的旧操作。标签视觉状态来自会话活动判断是session.idthis.activeDocumentSessionId活动标签使用强调文字、背景和底边非活动用次级文字。dirty由每个 session决定标题旁显示标记而不是读取全局documentDirty。后台标签即使不活动也能显示未保存。名称限制单行并省略避免超长文件名撑开整个工具栏。完整名称可通过 tooltip或无障碍文本提供。固定标签高度让 dirty标记和关闭图标不会改变布局。点击切换有异步互斥privateasyncactivateDocumentSession(sessionId:string):Promisevoid{if(sessionIdthis.activeDocumentSessionId||this.operationInProgress){return;}// 捕获当前、应用目标、激活 EditorState}保存、文件选择或目录操作期间不切换避免异步返回写到错误标签。点击当前标签也直接返回不重复捕获和重绘。Web激活恢复完整 EditorState因此光标、选择和历史保留。切换完成后回报字数与 dirty状态栏跟随目标。关闭按钮不能冒泡成切换标签行本身点击激活关闭按钮点击请求关闭。实现需要保证关闭按钮事件不会先触发父容器切换尤其关闭后台脏标签时。ArkUI控件的事件传播应在模拟器验证不能只看业务函数。关闭图标使用系统 symbol和无障碍文本.accessibilityText($r(app.string.close_document)).onClick(()this.requestCloseDocumentSession(session.id))熟悉的叉号不需要文字按钮占空间tooltip/读屏说明动作。触控目标必须大于图标视觉尺寸适配鼠标与触摸二合一设备。脏标签有三分支未保存标签显示取消、放弃、保存。取消保留放弃明确删除保存等待 URI选择和写入成功。点击保存不立即关闭最终只有目标仍活动且documentDirtyfalse才提交。后台脏标签先激活再保存因为当前保存管线使用活动页面字段。激活失败则不关。选择器取消、Mixed换行取消、冲突和写入失败都保持标签。关闭后的后继规则constnextIndexMath.min(sessionIndex,remainingSessions.length-1);constnextSessionremainingSessions[nextIndex];关闭中间标签原索引的新项是右侧邻居关闭最后项选择新末尾。用户空间记忆比每次跳到第一个更自然。先 apply并激活后继再删除旧 Web快照避免无活动 state中间帧。关闭后台标签不影响当前编辑器。最后一个标签关闭数组为空时创建新 Untitledif(remainingSessions.length0){remainingSessions[createUntitledSession(this.createDocumentSessionId())];}工作台始终有编辑目标快捷键与打开命令不需要零会话分支。用户感知是回到空白文档。窄窗口与溢出当前最多十二项标签栏需要水平容纳或滚动。固定上限不能保证小窗口不溢出。自由窗口最小宽度640vp侧边栏在900以下隐藏为标签释放空间名称使用省略。长期应为标签区增加水平滚动、活动标签自动滚入视图、鼠标滚轮横向切换或溢出菜单。不能让工具栏 Open/Save/模式控件被标签挤出。标签拖动排序、固定和最近关闭属于后续能力。鸿蒙 PC 模拟器结果下图显示两个独立标签活动底边、文件图标、关闭按钮和新建入口均在桌面工具栏中。两个标签正文独立dirty状态不会串联。键盘与可访问性成熟 PC标签需要 Ctrl/CmdW关闭、CtrlTab切换、Ctrl/Cmd数字定位、键盘焦点可见。当前核心快捷键集中在保存、打开和查找标签快捷键仍需实现。新增时应由原生层统一路由避免 ArkWeb和 ArkUI同时处理。读屏需要宣布文件名、活动状态、未保存状态和关闭动作。只在颜色和星号表达 dirty不足以满足可访问性标签 accessibilityText应组合这些语义。当前边界十二标签是固定上限没有后台冻结没有标签滚动和溢出菜单不持久化跨进程会话没有拖动、固定、批量保存和退出汇总完整多标签崩溃恢复未实现。边界明确后标签系统仍可靠覆盖主要多文档写作。后续扩展应围绕 DocumentSession身份不重新以标题或索引管理状态。结语标签栏不是装饰它把会话身份、URI、dirty、EditorState和关闭事务呈现给用户。十二上限控制内存稳定 id保证声明式身份URI去重防止同文件冲突空白复用减少噪音后继规则保持桌面空间记忆。鸿蒙 PC Markdown编辑器先保证每个可见标签都对应一份不会串线、不会误关的真实会话再增加拖动和固定才是正确顺序。