如何创建 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 元素,如 body
、div
或一些 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
对象上可用?
要实现这一点,您有两个选择:
- 使用 Webpack 并为输出指定
libraryTarget
。它可以是 umd
或类似的。阅读更多 here.
- 如果你不能使用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 将为您处理其他一切。
如何公开一个可以渲染 preact 应用程序的函数,我可以在其中传递渲染位置和道具?
preact中没有webpack配置可以修改,如何实现?
我看过 preact-habitat 插件,无法通过将 props 传递给函数来呈现小部件。
对于我的用例,我需要创建一个 bundle.js,其中包含多个可嵌入的小部件和 preact 源。
我可以调用 renderWidgetA(position, props), renderWidgetB(position, props) 来渲染它到 position,我也需要将不同的 props 传递给现有渲染的 widget
有什么办法可以实现吗?
这和svelte的逻辑类似:
非常感谢任何反馈。
假设按位置,你的意思是安装 HTML 元素,如 body
、div
或一些 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
对象上可用?
要实现这一点,您有两个选择:
- 使用 Webpack 并为输出指定
libraryTarget
。它可以是umd
或类似的。阅读更多 here. - 如果你不能使用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 将为您处理其他一切。