我的问题始于我想在外部网站中使用一个组件作为小部件。首先,我使用React Router创建了一个路由来仅打印该组件,以便我可以在iframe中使用它,但问题是该组件有下拉菜单,因此当它们打开时,您必须滚动才能访问它们。
因此,我在互联网上研究了如何使组件“可小部件化”,但我找不到任何东西,或者至少找不到清晰的内容。
我的问题是,有没有一种方法可以将我的组件与样式和所有内容分开导出,以便将其用作外部网站的小部件?是否有一种标准方法来实现这一点?
此外,是否有一种方法可以通过webpack编译组件?如果可能的话,编译后如何在外部网站中使用它?
为了给您更多信息,我的组件是一个表单,该表单具有下拉日历和弹出窗口,并且使用react-router在/widgets/form上创建了一个路由,仅打印表单组件。
谢谢阅读!
更新1
我希望避免在外部网站中添加React,我只想让他们向其正文添加JS片段,就像这样:
当我执行它时,控制台会抛出一些错误:
因此,我在互联网上研究了如何使组件“可小部件化”,但我找不到任何东西,或者至少找不到清晰的内容。
我的问题是,有没有一种方法可以将我的组件与样式和所有内容分开导出,以便将其用作外部网站的小部件?是否有一种标准方法来实现这一点?
此外,是否有一种方法可以通过webpack编译组件?如果可能的话,编译后如何在外部网站中使用它?
为了给您更多信息,我的组件是一个表单,该表单具有下拉日历和弹出窗口,并且使用react-router在/widgets/form上创建了一个路由,仅打印表单组件。
谢谢阅读!
更新1
我希望避免在外部网站中添加React,我只想让他们向其正文添加JS片段,就像这样:
((d, s, u) => {
const h = d.getElementsByTagName(s)[0],
j = d.createElement(s);
j.async = true;
j.src = 'http://localhost:3000/files/widgets/ibb-form.min.js';
j.onload = () => {
console.log('Widget: ibblue form loaded!');
start({ url: u });
};
h.parentNode.insertBefore(j, h);
})(document, 'script', 'http://localhost:3000/widgets/form');
function start({ url }) {
new window.IBBForm({ url });
}
我在这个片段中使用的JS代码如下:
(() => {
const IBBForm = class {
constructor({ id, url }) {
this._elementID = id || '#ibblue_form';
this._target = document.querySelector(this._elementID);
if (!url) throw new Error('No URL specified');
this._url = url;
this._iframe = this._createIframe();
this._target.append(this._iframe);
}
_createIframe() {
const iframe = document.createElement('iframe');
iframe.id = 'ibblue_form_iframe_' + new Date().getTime();
iframe.src = this._url;
iframe.style =
'width: 100%; height: 600px; border: medium none; background-color: transparent; display: initial;';
iframe.allowTransparency = 'true';
return iframe;
}
};
window['IBBForm'] = IBBForm;
})();
更新二
我修改了下载的脚本,使其变为以下内容:
import BookingSearch from './../../src/components/sections/BookingSearch';
(() => {
const IBBForm = class {
constructor({ id, url }) {
this._elementID = id || '#ibblue_form';
this._target = document.querySelector(this._elementID);
if (!url) throw new Error('No URL specified');
this._url = url;
this._addRequirements().then(() => {
this._element = this._createForm();
});
}
async _addRequirements() {
await this._addScript('https://unpkg.com/react@17/umd/react.production.min.js');
await this._addScript('https://unpkg.com/react-dom@17/umd/react-dom.production.min.js');
}
async _addScript(url) {
return new Promise((resolve, reject) => {
const h = document.getElementsByTagName(s)[0],
j = document.createElement(s);
j.async = true;
j.type = 'module';
j.src = url;
j.crossorigin = '';
j.onload = resolve();
h.parentNode.insertBefore(j, h);
});
}
_createForm() {
return ReactDOM.render(<BookingSearch widget={true} dataTheme={{}} />, this._target);
}
};
window['IBBForm'] = IBBForm;
})();
当我执行它时,控制台会抛出一些错误:
Uncaught SyntaxError: expected expression, got '<'
Uncaught TypeError: window.IBBForm is not a constructor
ReactDOM.render(<YourWidget />, '#foo')
进行渲染。 - aziumReactDOM.render
,以便消费者可以调用您的函数来调用 React。 - azium