@fulate/vue

Vue adapter 把 Vue renderer 接到一个 Fulate `Root`。它不复制 Core 场景状态,也不创建第二个 Root frame runtime;每个挂载的应用只拥有自己的 content/overlay Layer 和 Vue 生命周期。
2,175
Install
npm install @fulate/vue
Latest Version:1.0.19
Vue:3
License:MIT
Last Updated:Oct 9, 2026
Links: npm
Maintainer: 247076126zr

@fulate/vue

Vue adapter 把 Vue renderer 接到一个 Fulate Root。它不复制 Core 场景状态,也不创建第二个 Root frame runtime;每个挂载的应用只拥有自己的 content/overlay Layer 和 Vue 生命周期。

创建与挂载

import { createApp } from "@fulate/vue";

const app = createApp(App);
app.mount(container);       // 自动创建并拥有 Root
// 或:app.mount(root);      // 使用已有 Root,Root 仍由调用方拥有

app.unmount();

传入 HTMLElement、选择器或已有 Root。自动创建的 Root 由 app 释放;传入已有 Root 时,app 只 释放自己创建的 Layer 和 renderer。一个 Root 只能承载一个 Fulate Vue app;应用不可在 unmount 后 重新挂载。初次 onMounted() 中卸载 app 或 Root,也会结束该次 Vue scope。

使用 Yoga 标签时导入 @fulate/vue/yoga;@fulate/components 已完成该注册。Vue 主入口可单独使用, Yoga 是适配入口的可选 peer dependency。

VueShape 与自定义元素

VueShape 在元素进入活动 Root 时挂载 Vue component,离开时卸载。它支持两种互斥的 props 模式。

低层 manual 模式通过 setComponentProps() 采用 whole-value props,同一引用是 noop。组件可通过 registerVueComponent(name, component) 注册,以便基础 clipboard/file adapter 按名称恢复:

import { VueShape, registerVueComponent } from "@fulate/vue";

registerVueComponent("Badge", Badge);
const badge = new VueShape({ width: 120, height: 32 }, { label: "Ready" })
  .bindComponent(Badge);

mapped 模式使用 VueShape<P, O> 和第三个构造参数安装 typed Properties,并在 bindComponent() 时注册一次 properties resolver。resolver 读取包含 configured/runtime 的最终 effective Properties, 每次返回完整 props;Fulate 通过同一 setComponentProps() 路径整体替换:

class KeyValueShape extends VueShape<KeyValueProperties, KeyValueOption> {
  override readonly type = "key-value";

  constructor(options: KeyValueOption = {}) {
    super(options, {}, new KeyValueProperties(options));
    this.bindComponent(FKeyValue, (current) => ({
      keyText: current.runtimeKeyText ?? current.keyText,
      valueText: current.runtimeValue ?? current.valueText
    }));
  }
}

初始绑定、configured/runtime 更新与清除、属性快照恢复都经过该映射。mapped props 是派生缓存,不写入 JSON、Clipboard 或 History;mapped 业务类型由其具体 type factory 恢复。manual 模式仍保存组件名称和 手动 component props,fromVueToFulate() 与基础 vueClipboardPlugin 的行为不变。

每个 VueShape 都拥有独立 Vue app。组件可在 setup() 中直接通过 useFulateHost() 取得当前宿主; 派生类型可作为泛型参数保留具体类型:

import { useFulateHost } from "@fulate/vue";

const shape = useFulateHost<KeyValueShape>();

该注入只存在于 VueShape 创建的独立 app;外层 Editor Vue app 的 provide() 不会自动穿透。Root、 overlay 和 size 上下文仍由每个独立 app 分别提供。

自定义 Canvas 元素通过 registerElement("f-widget", Widget) 注册后,才能在 Vue template 中使用 <f-widget />。未知元素会在 renderer 创建时自然抛错,不另设兼容路径。

Root 与 overlay

createApp() 会建立内容层和 overlay 层,并通过 FULATE_ROOT_KEY、FULATE_OVERLAY_KEY 注入给 Vue 组件。手工管理 Root 时,可用 registerVueOverlay(root, layer) 为独立 VueShape 提供浮层层; 返回的 cleanup 必须在场景销毁时调用。

const unregister = registerVueOverlay(root, overlayLayer);
// ... mount VueShape / use overlay composables
unregister();

组件尺寸可通过 useVueShapeSize() 读取。过渡动画使用 FTransition,其动画仍通过元素的正常 animate() 与 Root frame 路径完成。registerVueOverlay() 和组件 overlay 定位的 cleanup 绑定 所属 Root 生命周期;useOverlayPosition() 的异步结果只在 task、引用和挂载状态仍有效时安装。

Clipboard

vueClipboardPlugin 是按 Select 实例显式安装的 clipboard adapter:

const select = new Select().useClipboard(vueClipboardPlugin);

基础 manual VueShape 的复制 payload 保存组件名称、props 和必要元素数据,组件必须在恢复前完成 注册。mapped 自定义类型不保存组件名称或派生 props,由业务 type factory 恢复。该 adapter 不注册 全局 Select 行为,也不读取旧格式。

Version History

Version Released License
1.0.19 MIT
1.0.15 MIT
1.0.14 MIT
1.0.13 MIT
1.0.12 MIT