Skip to content

集成外部工具

ElfUI 不需要为每个图表、编辑器、renderer、overlay、Observer、Worker 或 WASM 包内置 adapter。把工具视为外部资源的拥有者,并把资源所有权绑定到组件生命周期即可。

基本契约

  1. setup 阶段创建 template ref。
  2. onMounted 初始化工具,此时最终 DOM 与 ref 已就绪。
  3. 响应式数据变化通过工具自身的 update API 传入。
  4. 卸载时停止 Observer、监听器、timer、Worker、portal 和工具实例。
  5. 让异步任务失效,避免旧任务完成后写入已经断开的组件。
ts
import {
  defineHtml,
  onMounted,
  useTemplateRef,
} from "@elfui/core";

const canvas = useTemplateRef<HTMLCanvasElement>("canvas");

onMounted(async () => {
  const { createRenderer } = await import("some-dom-tool");

  if (!canvas.value?.isConnected) return;
  const instance = createRenderer(canvas.value);
  return () => instance.destroy();
});

export default defineHtml(`<canvas ref="canvas"></canvas>`);

示例包名只用于说明模式,ElfUI 不会打包它。

跟踪尺寸与可见性

Observer 组合式函数接受 element、ref 或响应式 getter。应传入 ref 本身,让观察在 mounted 后开始并跟随目标替换:

ts
const canvas = useTemplateRef<HTMLCanvasElement>("canvas");

useResizeObserver(canvas, ({ width, height }) => {
  renderer?.resize(width, height);
});

useIntersectionObserver(canvas, ({ isIntersecting }) => {
  isIntersecting ? renderer?.resume() : renderer?.pause();
});

两个 helper 都会随所属组件断开,并忽略旧目标的延迟回调。浏览器没有对应 Observer API 时会安全地保持未启用状态。

资源所有权规则

资源创建位置释放方式
图表、编辑器、renderer 实例onMounted返回工具的 destroy() 清理函数
全局 DOM 监听器useEventListener 或 mountedhelper 自动清理或 removeEventListener
Resize/Intersection ObserverObserver 组合式函数自动
Portal/overlay rootonMounted移除监听器与空 portal 节点
WorkeronMounted 或所属 effect忽略旧消息,再调用 terminate()
Timer/animation framemounted 或所属 effectclearTimeout / cancelAnimationFrame
异步 import/request/WASM setupmounted generation/tokenteardown 前失效或 abort

同一轮事件循环内的同步 DOM move 会保留组件实例。真正断开时资源会释放,稍后重连会创建新实例并再次执行 onMounted。异步 mounted 钩子在卸载后才返回清理函数时,ElfUI 会立即执行它。KeepAlive 失活不等于卸载:在 onDeactivated 暂停昂贵工作,在 onActivated 恢复,最终通过 mounted 清理函数或 onUnmounted 销毁。

发布门禁覆盖

ElfUI 集成套件会在真实 Chromium 中运行 DOM 接管、Canvas 图表、SVG/WebGL、Shadow DOM overlay/portal、原生 Observer/全局监听器、Worker/WASM 取消、异步竞态、分支和 keyed list 释放、KeepAlive 淘汰、App unmount,以及 100 轮重复挂载/卸载。这些包只属于测试用开发依赖,不会进入发布包。

这套测试验证的是框架生命周期与平台边界;应用仍应针对自己选用的外部工具版本和配置运行集成测试。