如何创建 preact 多个可嵌入小部件?

How to create preact multiple embeddable widget?

如何公开一个可以渲染 preact 应用程序的函数,我可以在其中传递渲染位置和道具?

preact中没有webpack配置可以修改,如何实现?

我看过 preact-habitat 插件,无法通过将 props 传递给函数来呈现小部件。

对于我的用例,我需要创建一个 bundle.js,其中包含多个可嵌入的小部件和 preact 源。

我可以调用 renderWidgetA(position, props), renderWidgetB(position, props) 来渲染它到 position,我也需要将不同的 props 传递给现有渲染的 widget

有什么办法可以实现吗?

这和svelte的逻辑类似:

非常感谢任何反馈。

假设按位置,你的意思是安装 HTML 元素,如 bodydiv 或一些 CSS 选择器,如 '#mountElm',那么你可以导出像这样的渲染函数:

import { render, h } from 'preact';

// WidgetA is a Preact component.
// It could be functional or class component.
export function WidgetA(props) {

    // Use props here

    return (
        <div>WidgetA</div>
    );
}


// Render function for WidgetA
export function renderWidgetA(position, props) {

    const renderElm = position instanceof HTMLElement
        ? position
        : document.querySelector(position);

    render(h(Component, props), renderElm);
}

当这个文件被打包后,可以像这样简单地使用:

import { renderWidgetA } from './my-bundle.js';

renderWidgetA('body', { title: 'Hello world' });

您可以按照类似的模式创建多个组件。此外,您可以简单地将渲染函数提取到更通用的变体中。

问题 1:如何使函数在全局 window 对象上可用?

要实现这一点,您有两个选择:

  1. 使用 Webpack 并为输出指定 libraryTarget。它可以是 umd 或类似的。阅读更多 here.
  2. 如果你不能使用Webpack或者禁止更改它,那么在文件的末尾,你可以明确地将它绑定到一个全局对象。

示例:

window.myLib = { renderWidgetA };

// Usage
myLib.renderWidgetA('body', { /* some props */});

问题二:某个widget的prop发生变化怎么办

您必须对 render 函数进行更改。它接受可选的 third parameter,您可以将其设置为 true。所以你的函数变成:

export function renderWidgetA(position, props) {

    const renderElm = position instanceof HTMLElement
        ? position
        : document.querySelector(position);

    // NOTE THE THIRD PARAM
    render(h(Component, props), renderElm, true);
}

曾经,只要您的道具发生变化,您只需调用 renderWidgetA 函数即可。它是完全无害的。只需确保您的位置节点在多次重新渲染中保持不变即可。另外,永远记住 UI 作为状态函数 。 VDOM 将为您处理其他一切。