Skip to content

追加与覆盖 Widget(L5 / L6) ​

逻辑 widget 在 Core,真正的 render() 在 Adapter。

L5:追加,不覆盖 ​

createElementPlusAdapter({ widgets })(以及 Antd / shadcn 的对应工厂)用 mergeExclusive:已有内置 key 不会被覆盖,只能加新 key。

ts
import { createElementPlusAdapter } from "@xunserver-jsf/element-plus";

const adapter = createElementPlusAdapter({
  widgets: {
    "company.currency": currencyBinding, // WidgetBinding:codec + render
  },
});

FormRenderer 可以直接 :adapter="adapter"。这够用在「新增业务控件」。

L6:替换内置 ​

要换掉 text 等内置 key,必须 extend*Adapter + create*RendererEnvironment 的精确 override。冲突键是 (adapterId, registryKind, key)。wildcard 与未消费 override 会阻断构建。

ts
import { createVueRendererEnvironment } from "@xunserver-jsf/vue";
import { createElementPlusAdapter, extendElementPlusAdapter } from "@xunserver-jsf/element-plus";

const environment = createVueRendererEnvironment({
  adapters: [createElementPlusAdapter()],
  contributions: [
    extendElementPlusAdapter({
      owner: "app",
      widgets: { text: appTextBinding, "company.currency": currencyBinding },
    }),
  ],
  overrides: [
    {
      adapterId: "element-plus",
      registry: "widgets",
      key: "text",
      expectedOwner: "element-plus",
      replacementOwner: "app",
    },
  ],
});
vue
<FormRenderer :form="form" :environment="environment" adapter-id="element-plus" />

FormRenderer 的 adapter 与 environment+adapterId 二选一,不能同时传。

Custom binding 只能拿到 readonly descriptor、snapshots、scope view 与 setValue / touch / focus / blur。对照实现:examples/playground/src/previews/*/renderer.ts。