# 4-1 [recycle] Sidebar / 页面树 / 文件树 产品级差距分析 v1 > 更新时间:2026-04-17 > > 关联文档: > - `/mnt/Data1T/mnote/design/04-tree-domain/process/4-sidebar-pagetree-filetree-rust-web-rebuild-v1.md` > - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-tree-first-graph-kernel-v1.md` > - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-1-tree-first-graph-kernel-checklist-v2.md` ## 1. 文档目的 这份文档不回答: - “当前新树能不能先凑合继续用” - “再补一点样式是不是就够了” 这份文档回答的是: > **当前 git 中已经接入的 Rust Web tree shell,距离“文件树对标 VS Code、页面树对标 Wolai / Notion”的产品目标还差什么,以及下一步应该如何推进。** 结论先固定: - 当前方向没有跑偏 - 当前实现仍然只是过渡 shell,不是产品级树控件 - 下一步重点不是继续修饰过渡 shell,而是进入“产品级树域控件重建” --- ## 2. 当前实现所处阶段 根据当前 git 中未提交改动,现状应被定义为: - 已完成 tree shell 挂载位 - 已完成 `mnote-web /tree` 路由与基本 command 回写 - 已完成 Sidebar / 文件树 / picker 的渐进切流入口 - 尚未完成产品级树交互能力重建 也就是说,当前完成的是: - **协议验证** - **切流验证** - **最小可运行壳验证** 而不是: - **VS Code 级文件树** - **Wolai / Notion 级页面树** ### 2.1 当前代码中已经成立的部分 - `wolai-frontend` 已经可以把树域挂到 `mnote-web tree shell` - `mnote-web` 已经可以输出基础 tree projection 并承接 create / rename / move - 新旧树之间已经有 feature flag 与 fallback 对应实现可参考: - `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/sidebar.tsx` - `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/MnoteWebTreeShell.tsx` - `/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/tree.rs` ### 2.2 当前实现不能被误判为“已完成重构”的原因 当前 `mnote-web tree shell` 仍然具有明显过渡壳特征: - 通过 `iframe + postMessage + fallback` 接入主站 - 壳内 UI 仍是手写 HTML / CSS / DOM 逻辑 - 交互动作仍大量依赖 `prompt` / `alert` - 没有完成稳定的 row model / focus model / selection model / keyboard model / DnD state machine 这类实现适合做: - 协议对齐 - route 验证 - 真机切流 不适合直接作为: - 最终产品树控件 --- ## 3. 现阶段的关键判断 ### 3.1 方向没有错 当前路线与长期架构是一致的: - 树真相继续下沉到 kernel / projection - 页面树与文件树继续作为 projection family - Sidebar 继续降级为树域承载壳 所以,“把树域逐步从旧 React 组件中剥离出来”这个方向是对的。 ### 3.2 体验回退是阶段性真实现象 用户现在觉得新树在操作和界面上与目标产品差距很大,这个判断是正确的。 原因不是: - 目标错了 而是: - 当前切进去的是过渡 shell - 旧 React 树实际上已经沉淀了一部分成熟交互 - 新 Rust Web 壳还没有把这些产品交互能力重新建起来 ### 3.3 当前最危险的误区 当前最应该避免的,不是“改慢一点”,而是下面两个误区: - 误区 A:把过渡 shell 继续当最终产品打磨 - 误区 B:看到效果差,就退回“继续长期维持旧树 + 新协议双轨” 正确做法是: - 承认当前只是过渡壳 - 用它验证协议与切流 - 然后进入产品级树控件重建 --- ## 4. 当前实现与目标产品的差距矩阵 ## 4.1 文件树:目标应对标 VS Code Explorer 这里的“对标”不是抄界面,而是对标: - 行为模型 - 信息密度 - 交互反馈 - 结构表达 ### 当前已经具备的部分 - 已有文件树入口 - 已有页面与附件的基础层级表达 - 已有打开页面 / 打开附件的最小动作链路 - 主站旧文件树中已沉淀部分 VS Code 风格拖放语义 ### 当前缺失的关键能力 - 缺少稳定的文件树专用 row model - 缺少真实的 `filetree` 模式闭环 - 缺少多选与连续选择 - 缺少键盘导航 - 缺少目录型拖放状态机 - 缺少重命名内联编辑 - 缺少右键菜单体系 - 缺少 hover 工具动作 - 缺少大树虚拟化与增量展开策略 - 缺少图标语义与资源类型区分 ### 当前与 VS Code 的本质差距 当前新壳更像: - “能渲染树结构的调试页” 而 VS Code Explorer 是: - “高密度、可键盘驱动、可多选、可拖放、可重命名、可上下文操作的文件资源管理器” 所以文件树下一阶段不应再以“补几个按钮”为目标,而应以“重建 Explorer 行为模型”为目标。 ## 4.2 页面树:目标应对标 Wolai / Notion 这里的“对标”不是纯视觉复刻,而是对标: - 页面层级表达方式 - hover 操作节奏 - 新建 / 展开 / 拖拽 / 上下文动作的一致性 - 页面树作为知识库导航入口的轻量感 ### 当前已经具备的部分 - 已有页面树 projection 主链 - 已有基础展开 / 新建 / 重命名 / 上下移动作 - 已有主站切流挂载位 ### 当前缺失的关键能力 - 缺少 hover 暴露的轻量动作区 - 缺少更细的页面类型 / 状态表达 - 缺少更自然的层级拖拽交互 - 缺少键盘导航与 focus 管理 - 缺少右键菜单与上下文操作体系 - 缺少行级局部状态管理 - 缺少高密度列表的稳定渲染与滚动体验 - 缺少与搜索、跳转、最近访问状态的联动边界 ### 当前与 Wolai / Notion 的本质差距 当前新壳更像: - “展示树数据并支持几个命令” 而 Wolai / Notion 页面树更接近: - “低干扰导航器 + 轻量页面管理器” 所以页面树下一阶段的重心不是“增加更多按钮”,而是: - 让操作默认隐藏、按需显现 - 让层级结构更轻 - 让拖拽、展开、新建、上下文菜单进入一致的节奏 ## 4.3 Sidebar:目标不是单独对标某产品,而是成为稳定壳 在长期架构中,Sidebar 的任务不是持有树真相,而是: - 承载 projection - 承载搜索入口 - 承载快速切换 - 承载少量工作区级操作 所以 Sidebar 的核心问题不是“左栏长什么样”,而是: - 树域壳与主站其它能力之间的耦合是否被切干净 当前 Sidebar 仍然偏重,说明下一阶段除了树控件本身,还要继续做: - Sidebar 壳职责收敛 - 树域与其它面板解耦 - 搜索 / AI / 树域三者的边界整理 --- ## 5. 当前代码中的具体偏差 ## 5.1 `filetree` 模式闭环仍不完整 当前主站已向新壳传入 `mode=\"filetree\"`,但 Rust route 与壳内脚本对模式的识别还没有完整闭环。 这意味着当前“文件树已切到新壳”不能简单视为已经完成。 这一点必须优先修正,因为它会直接影响: - 文件树功能判断 - 测试结果判断 - 后续重构任务拆分 ## 5.2 新壳仍是协议验证页,不是产品树控件 当前树壳使用: - 手写 HTML 模板 - 手写 DOM 生成树节点 - 手写按钮动作 这在协议验证阶段是合理的,但不应继续长期积累。 如果继续在这一层追加: - hover 细节 - 菜单 - 多选 - DnD - keyboard 最终只会把过渡壳演化成难维护的第二套前端。 ## 5.3 旧树的成熟交互能力尚未被系统迁移 旧文件树与旧页面树中,已经沉淀出一部分成熟能力: - 文件树的拖放反馈 - 文件树的多选与内部拖放 - 页面树的虚拟化 - 页面树的拖拽排序 这些能力现在还没有以“协议化行为模型”的方式迁移进新树域,而是仍然留在旧 React 实现里。 这意味着下一阶段不能只盯新壳,还要做一件关键工作: - 把旧树中已经证明有效的交互经验抽象成正式产品合同 --- ## 6. 下一阶段应如何指导修改 ## 6.1 原则一:停止把过渡 shell 当最终实现打磨 接下来不应继续以如下方式推进: - “再补几个按钮” - “再修一版样式” - “再把这个 iframe 页面做像一点” 这些动作只能缓解表面问题,不能得到产品级树控件。 正确方式是: - 把当前壳明确标记为过渡验证层 - 只修协议、切流、阻塞性错误 - 不在这里继续堆复杂交互 ## 6.2 原则二:先冻结产品交互合同,再进入 Rust Web 正式实现 下一阶段首先要做的,不是直接写更多 UI,而是冻结两份合同: - 文件树产品交互合同 - 页面树产品交互合同 这两份合同至少应明确: - 行模型 - 层级缩进规则 - active / selected / focused / dragging 的区别 - hover 暴露策略 - 右键菜单入口 - 键盘导航规则 - 多选规则 - 拖放语义 - 内联重命名规则 - 空白区与容器区行为 ## 6.3 原则三:旧树不是要照抄,而是要提炼成熟行为 当前仓库里旧树实现仍然有直接参考价值: - `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/file-tree.tsx` - `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/private-tree.tsx` 它们的价值不在于: - 继续长期保留 React 版本 而在于: - 可以作为“已在当前产品中验证过的交互基线” 下一阶段应从它们中提炼: - 哪些交互是必须保留的 - 哪些只是过渡做法 - 哪些要升级成正式协议字段或 UI 状态机 ## 6.4 原则四:文件树与页面树应共用一套树行为骨架 下一阶段不要再走两套完全独立实现。 应采用: - 同一套 tree row model - 同一套 selection / focus / keyboard / drag state - 同一套 command dispatch 然后在 projection 层区分: - `page_tree` - `file_tree` 这样才能保持: - 文件树不是孤立系统 - 页面树不是孤立系统 - 两者继续服从 `tree-first graph kernel` ## 6.5 原则五:最终目标应是产品级 Rust Web tree shell,而不是长期 iframe 壳 长期上,目标应当是: - Rust Web 正式树控件 - 直接消费 projection protocol - 直接发 command protocol - 主站以内嵌挂载或原生整合方式承载 而不是: - 长期保留 `iframe + postMessage + fallback` 作为正式方案 `iframe` 在当前阶段的价值是: - 降风险切流 - 降低对主站的侵入 它不应成为最终交付形态。 --- ## 7. 建议采用的参考体系 ## 7.1 最值得参考:行为模型参考 优先级最高的不是某个“现成树组件”,而是行为模型参考。 推荐优先参考: - `headless-tree` 主要借鉴内容: - row model - selection - focus - keyboard - drag and drop 状态拆分 这类参考最适合解决: - 为什么树一旦复杂就开始失控 - 为什么文件树与页面树经常需要重复写交互 ## 7.2 产品结构参考 推荐参考: - `AppFlowy` - `AFFiNE` 主要借鉴内容: - Sidebar 与页面树的产品层边界 - 工作区 / 页面 / 文档之间的协作关系 - 页面树如何作为知识产品的导航层 不建议直接借: - 大量样式实现细节 - 与当前架构不一致的事实源模型 ## 7.3 Rust Web UI 参考 推荐参考: - `Leptos` - `radix-leptos` - `thaw` 主要用途: - 实现正式 Rust Web tree shell - 补齐 collapsible / menu / scroll area / overlay 等 primitives ## 7.4 不建议作为主导参考的对象 以下可以看,但不应成为主导路线: - 终端树组件 - 桌面 GUI 树组件 - 纯列浏览器方案 原因是它们无法直接回答当前最核心的问题: - 如何在 Web 主站中实现产品级页面树 / 文件树 --- ## 8. 下一阶段的任务拆分建议 ## 8.1 阶段 A:修正当前过渡壳中的协议闭环问题 只处理阻塞项: - 修正 `filetree` 模式闭环 - 校正 projection / mode / consumer 对应关系 - 补齐最小测试 这一阶段不做: - 大规模 UI 打磨 - 新交互堆叠 ## 8.2 阶段 B:产出页面树 / 文件树产品交互合同 必须单独落文档,至少包含: - 文件树对标 VS Code 的功能矩阵 - 页面树对标 Wolai / Notion 的功能矩阵 - 当前已实现 / 未实现 / 不做 的判定 - 对 projection 和 command 的新增要求 ## 8.3 阶段 C:实现正式 tree row model 与状态骨架 这一阶段要优先完成: - row model - selection model - focus model - keyboard model - drag state - context menu entry model 这一层最好先独立,再挂 UI。 ## 8.4 阶段 D:实现产品级 Rust Web tree shell 这一阶段才进入正式 UI: - 页面树 renderer - 文件树 renderer - picker renderer - 统一 shell 挂载 ## 8.5 阶段 E:收敛旧树实现 最后再做: - 旧文件树 helper 清理 - 旧页面树 helper 清理 - 旧 Sidebar 树域状态清理 - 旧 consumer 收口 --- ## 9. 最终结论 当前实现与设计之间,不存在“方向性错误”,但存在明显的“阶段性落差”。 这个落差的本质不是: - 少几个按钮 - 样式还不够像 而是: - 当前完成的是树域过渡 shell - 目标要求的是产品级树控件系统 因此,接下来应明确口径: - 当前 git 中的新树实现,定义为**过渡验证层** - 下一阶段任务,定义为**产品级树域控件重建** 只有这样,团队后续的修改方向才不会继续发散。