From 8de1499c405754ff80060513ef17d42e319cbbf2 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Fri, 2 Oct 2026 09:04:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=E6=8F=92=E4=BB=B6=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E6=B3=A8=E5=85=A5=E8=A2=AB=E5=AE=BF=E4=B8=BB=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E9=87=8D=E5=BB=BA=E6=93=A6=E9=99=A4=20=E2=80=94=E2=80=94=20?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E5=9E=8B=E6=B3=A8=E5=85=A5=E4=BB=8E=E6=9C=AA?= =?UTF-8?q?=E7=9C=9F=E6=AD=A3=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 现象 部署示例后打开 WebUI:侧栏有 Billing 页,但**状态页上没有任何计费组件**。 插件明明声明了 elements,/api/ui-inject 也确实返回了 mount(1570 字节)。 ## 根因(不是缺功能) 七个宿主页面的渲染函数都用 `pane.innerHTML = ...` **整体替换**自己的 DOM。 `renderStatus` 在 `injectPluginUI()` 之后由 refresh() 立刻调用,于是刚挂上的 plugin-el 连同整个 pane 一起被下一次赋值销毁。 时序上它**从没有过"显示一帧"的机会**:注入 → refresh("status") → innerHTML 覆盖。 所以症状是"元素从来没出现过",而不是"刷新后消失"——这正是我先前据 /api/ui-inject 返回值判定"注入正常"而漏掉的地方:**载荷到达 ≠ DOM 存活**。 Billing 页不受影响,因为它属于 PLUGIN_PAGES,走插件自有 DOM,不经宿主重建。 于是看起来像"页面注入有效、元素注入无效",把排查引向插件声明本身。 ## 修法 - mountPluginElements 改成具名可重入函数,并注册进 PLUGIN_MOUNT_HOOKS - refresh() 在**唯一出口**统一调 remountPluginElements(),而不是给七个渲染函数 各加一次调用——后者是多一处会忘的地方,而忘记的后果是静默的 - 每个挂载点按 data-idx 幂等:宿主重绘时若该 pane 已有该元素就直接返回, 否则插件的