gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 10:57:53 25 4
gpt4 key购买 nike

如果我用纯 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 上类似地为应用程序制作插件?
自定义元素不太适合这个。

最佳答案

好吧,如果您愿意,也可以做一些非常相似的事情。 Svelte 只为您提供一个 UI 组件,您可以在页面上的任何位置呈现。它不会接管你的整个 JS。

一件事是您的 Svelte 应用程序很可能会使用 ES import 进行捆绑(Rollup 或 Webpack)陈述。这意味着你的代码将存在于 ES 模块中,局部变量不会自动附加到 window ES 模块中的对象。所以你必须明确这一点。所以你的代码会变成这样:

App.js (presumably your application entry point)

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 允许您通过 exporting const or function 向组件添加实例方法.

App.svelte

您可以导出 constfunction在 Svelte 组件上使用实例方法。

<script>

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

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

</script>
...

还有……瞧?您的代码中还有其他内容吗?

上述代码的一个问题可能是 App组件将在您的插件有机会注册之前呈现。

您可以使用 App 中的一个 Prop 来解决这个问题成分。为了能够从您的“ Controller 代码”更改此 Prop 的值,您可以使用 $set 组件的方法。您还可以设置 accessors组件上的选项。您可以使用捆绑插件选项全局执行此操作,或者您可以使用 <svelte:options> 在单个组件上启用它.

如果您需要一些仅在应用准备就绪后运行的自定义逻辑,您可以在 "reactive statement" 中执行此操作.

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
}
}

或者,您可能更愿意在 App 组件中移动插件初始化代码。由于您在这里有一个“静态”状态,因此在 appModules 中变量,您必须将其放入静态 <script context="module"> 您的组件的一部分:

App.svelte

<script context="module">
// 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
}
</script>

<script>
// 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
}
}
</script>

{#if ready}
...
{/if}

静态函数addPlugin可以作为其他模块的命名导出访问:

import { addPlugin } from './App.svelte'

这可能更适合捆绑应用程序/带模块的应用程序的上下文,而不是将内容附加到 window。 (因此在全局命名空间中遇到冲突的风险)。取决于你在做什么...

关于javascript - 如何为用 svelte.js 编写的应用程序创建插件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59266902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com