编辑器是 HexoPress 中最复杂的部分。它不仅要提供流畅的 Markdown 编辑体验,还要集成文件浏览、目录导航、媒体插入和 AI 辅助等功能。如何在不让界面变得臃肿的前提下容纳这些功能,是一个有趣的设计挑战。
核心与面板的分离
HexoPress 编辑器的设计思路是:核心编辑区域保持纯粹,辅助功能通过可切换的侧边面板提供。
编辑区域只关心两件事:Markdown 文本的编辑和 Front Matter 元数据的管理。它不知道也不关心旁边有什么面板。这种分离让编辑体验不受辅助功能的干扰——当你专注写作时,可以收起所有面板,获得最大的编辑空间。
侧边面板则是独立的功能模块,每个面板有自己的职责:
- 文件浏览器:导航博客的源文件目录
- 目录面板:展示当前文章的标题结构
- 媒体面板:浏览和插入图片资源
- AI 面板:与 AI 助手对话
这些面板之间互不依赖,可以独立开发和测试。
通过共享状态实现协作
面板虽然独立,但它们需要访问编辑器的上下文。比如,目录面板需要知道文章的标题结构,AI 面板需要读取文章内容或选中的文本。
HexoPress 的解决方案是将编辑器的关键状态提升到一个全局的状态管理器中。编辑器组件负责将自己的状态(文本内容、选中文本、标题列表、Front Matter 等)同步到这个共享空间,面板组件则从中读取需要的数据。
这种设计的好处是:
松耦合。 面板不需要直接引用编辑器组件,也不需要知道编辑器的内部实现。它们只依赖共享状态的数据结构。
可扩展。 添加新的面板只需要从共享状态中读取数据,不需要修改编辑器的代码。
可测试。 面板可以通过模拟共享状态来独立测试,不需要启动完整的编辑器环境。
选中文本的感知
一个有趣的细节是编辑器如何让外部组件感知到用户的文本选择。
编辑器内部会定期检查底层编辑引擎的选择状态,并将选中的文本和位置信息同步到共享状态中。这样,AI 面板就能知道用户当前选中了什么内容,从而提供「润色选中文本」这样的上下文相关功能。
这种轮询机制虽然不如事件驱动那么优雅,但它简单可靠,避免了在编辑引擎和 Vue 响应式系统之间建立复杂的事件桥接。
沉浸式写作体验
编辑器页面在路由层面与其他管理页面分离,使用独立的全屏布局。这意味着进入编辑器后,左侧的导航栏会消失,整个窗口都留给写作。
这个设计决策反映了一个理念:管理和写作是两种不同的心智模式。管理时你需要导航、筛选、概览;写作时你需要专注、沉浸、不被打扰。通过在路由层面分离这两种模式,HexoPress 让每种体验都能做到最好。
面向未来的扩展
模块化的面板设计为未来的功能扩展留下了空间。新的辅助功能可以作为新的面板加入,而不需要重构现有的编辑器架构。面板之间通过共享状态通信的模式,也让多个面板之间的协作变得自然。
如果你有兴趣为 HexoPress 贡献新的编辑器面板,这种架构会让你的工作变得相对简单——定义面板的 UI,从共享状态中读取需要的数据,就可以开始了。