首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何为用svelte.js编写的应用程序创建插件?

如何为用svelte.js编写的应用程序创建插件?
EN

Stack Overflow用户
提问于 2019-12-10 12:09:28
回答 2查看 739关注 0票数 2

如果我用纯JS编写应用程序,我会创建一个插件连接,如下所示:

App.js

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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上为应用程序制作插件?

自定义元素不太适合于此。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-10 22:52:28

嗯,如果你这么想的话,你也可以做一些类似的事情。Svelte只为您提供一个UI组件,您可以在页面上的任何地方呈现。它不会控制你的整个JS。

有一件事是,您的Svelte应用程序很可能会使用ES import语句捆绑(汇总或Webpack)。这意味着您的代码将驻留在ES模块中,并且局部变量不会自动附加到ES模块中的window对象。所以你得把这个说清楚。所以你的代码会变成这样:

App.js (想必是您的应用程序入口点)

代码语言:javascript
运行
复制
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

您可以导出constfunction以便在Svelte组件上具有实例方法。

代码语言:javascript
运行
复制
<script>

  export function regPlugin(...) { ... }

  // or
  export const sentToEventBus(...) { ... }

</script>
...

还有..。是吗?你的代码里还有别的东西吗?

使用上述代码,有一个问题可能是,在插件注册之前就会呈现App组件。

您可以通过App组件中的一个支柱来修复这个问题。为了能够从“控制器代码”中更改这个支柱的值,您可以使用组件的$set方法。还可以在组件上设置accessors选项。您可以通过一个绑定插件选项在全局上这样做,也可以使用在单个组件上启用它。

如果您需要一些只运行一次应用程序的自定义逻辑,您可以在“反应陈述”中这样做。

App.svelte

代码语言:javascript
运行
复制
<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

代码语言:javascript
运行
复制
document.onreadystatechange = function() {
  if (document.readyState === 'complete') {
    for (var module in appModules) {
      ...
    }

    app.$set({ ready: true })
    // or
    app.ready = true
  }
}

或者,您可能更喜欢移动App组件中的插件init代码。由于这里有一个“静态”状态,在appModules变量中,您必须将其放入组件的静态</code></a>部分:</div><blockquote><div>App.svelte</div></blockquote><pre><code>&lt;script context=&quot;module&quot;&gt; // this block only runs once, when the module is loaded (same as // if it was code in the root of a .js file) // this variable will be visible in all App instances const appModules = {} // make the appModules variable visible to the plugins window.appModules = appModules // you can also have static function here export function registerPlugin(name, plugin) { appModules[name] = plugin } &lt;/script&gt; &lt;script&gt; // in contrast, this block will be run for each new instance of App ... let ready document.onreadystatechange = function() { if (document.readyState === 'complete') { // NOTE appModules bellow is the same as the one above for (var module in appModules) { // ... } ready = true } } &lt;/script&gt; {#if ready} ... {/if}</code></pre><div>静态函数<code>addPlugin</code>可以作为来自其他模块的命名导出访问:</div><pre><code>import { addPlugin } from './App.svelte'</code></pre><div>这可能更适合与模块捆绑的应用程序/应用程序,而不是将东西附加到<code>window</code> (因此在全局命名空间中遇到冲突的风险)。取决于你在做什么。</div><div></div>

票数 2
EN

Stack Overflow用户

发布于 2019-12-10 22:19:46

这种类型的插件设置仍然有效,请查看客户端组件API

使用component.$set,您可以将道具从插件更改为svelte组件。

当您从svelte内部向您的插件/应用程序添加侦听器时,您可能需要额外的赋值,data = myPlugin.data才能对变化作出反应。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59266902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档