如果我用纯JS编写应用程序,我会创建一个插件连接,如下所示:
App.js
var App = function(){ /* ... */ };
//...
App.prototype.regPlugin= function ( atr1, atr2, ... ) { /* ... */ };
//...
App.prototype.sendToEventBus = function ( atr1, ... ) { /* ... */ };
//...
var app = new App();
//...
var appModules = {};
//...
document.onreadystatechange = function () {
if ( document.readyState === 'complete' ){
for ( var module in AppModules ) {
if ( AppModules[ module ] ) {
try {
AppModules[ module ].init( app );
} catch(er) {
//...
}
}
}
}
//...plugin.js
var MyPlugin = function (){ /*...*/ };
//...
MyPlugin.prototype.init = function ( app ) {
this.app = app;
//...
app.regPlugin( plugAtr0 );
//...
};
//...
MyPlugin.prototype.handleAny = function(){
this.app.sendToEventBus( /* my event */ );
};
//...
appModules.myPlugin = new MyPlugin();如何类似地在svelte.js上为应用程序制作插件?
自定义元素不太适合于此。
发布于 2019-12-10 22:52:28
嗯,如果你这么想的话,你也可以做一些类似的事情。Svelte只为您提供一个UI组件,您可以在页面上的任何地方呈现。它不会控制你的整个JS。
有一件事是,您的Svelte应用程序很可能会使用ES import语句捆绑(汇总或Webpack)。这意味着您的代码将驻留在ES模块中,并且局部变量不会自动附加到ES模块中的window对象。所以你得把这个说清楚。所以你的代码会变成这样:
App.js (想必是您的应用程序入口点)
import App from './App.svelte'
const app = new App({
target: document.body,
props: {
name: 'world',
},
})
const appModules = {}
// expose appModules as a global variable
window.appModules = appModules
document.onreadystatechange = function() {
if (document.readyState === 'complete') {
debugger
for (var module in appModules) {
if (appModules[module]) {
try {
appModules[module].init(app)
} catch (er) {
//...
}
}
}
}
}现在,app是您的根Svelte组件。它将驻留在一个App.svelte文件中。Svelte允许您通过function向组件添加实例方法。
App.svelte
您可以导出const或function以便在Svelte组件上具有实例方法。
<script>
export function regPlugin(...) { ... }
// or
export const sentToEventBus(...) { ... }
</script>
...还有..。是吗?你的代码里还有别的东西吗?
使用上述代码,有一个问题可能是,在插件注册之前就会呈现App组件。
您可以通过App组件中的一个支柱来修复这个问题。为了能够从“控制器代码”中更改这个支柱的值,您可以使用组件的$set方法。还可以在组件上设置accessors选项。您可以通过一个绑定插件选项在全局上这样做,也可以使用在单个组件上启用它。
如果您需要一些只运行一次应用程序的自定义逻辑,您可以在“反应陈述”中这样做。
App.svelte
<svelte:options accessors={true} />
<script>
export function regPlugin() {}
export function sentToEventBus() {}
export let ready = false
$: if (ready) {
// code to run when ready
}
</script>
{#if ready}
<!-- content to show when ready (all plugins initialized) -->
<!-- most likely, you'd put other Svelte components in there -->
{:else}
<div>Loading...</div>
{/if}然后,当应用程序准备好启动时,您可以切换这个道具:
App.js
document.onreadystatechange = function() {
if (document.readyState === 'complete') {
for (var module in appModules) {
...
}
app.$set({ ready: true })
// or
app.ready = true
}
}发布于 2019-12-10 22:19:46
这种类型的插件设置仍然有效,请查看客户端组件API。
使用component.$set,您可以将道具从插件更改为svelte组件。
当您从svelte内部向您的插件/应用程序添加侦听器时,您可能需要额外的赋值,data = myPlugin.data才能对变化作出反应。
https://stackoverflow.com/questions/59266902
复制相似问题