如何将 Svelte 应用程序用作另一个 Svelte 应用程序中的组件?

Posted

技术标签:

【中文标题】如何将 Svelte 应用程序用作另一个 Svelte 应用程序中的组件?【英文标题】:How to use a Svelte app as a component in another Svelte app? 【发布时间】:2021-12-21 10:32:18 【问题描述】:

用例:我有几个 Svelte 组件被编译为标准 Svelte 应用程序(即,不是 Web 组件),然后用于增强主 Svelte 应用程序的功能。

我正在使用典型的app = new SvelteApp(target, props) 方法通过包装器/代理组件(如suggested in this answer)实例化它们,这样我就可以执行以下操作:

MainApp.svelte

<script>
    import ComponentWrapper from 'ComponentWrapper.svelte'

    const App1 = window.app1; // this is standalone/compiled Svelte app
</script>

<ComponentWrapper this=App1 prop1="one" prop2="two" />

ComponentWrapper.svelte

<script>
    import  onDestroy  from 'svelte';

    let component;
    export  component as this ;

    let target;
    let cmp;

    const create = () => 
        cmp = new component( 
            target,
            props: $$restProps,
         );
    ;

    const cleanup = () => 
        if ( !cmp ) return;
        cmp.$destroy();
        cmp = null;
    ;

    $: if ( component && target ) 
        cleanup();
        create();
    

    $: if ( cmp ) 
        cmp.$set( $$restProps );
    

    onDestroy( cleanup );
</script>

<div bind:this=target />

这很好用,只是我无法使用 ComponentWrapper 上的 on:event= 指令或其中的 div 元素监听 App1 和 App2 调度的事件。

我的问题是:

    有没有更好的方法来包含独立的 Svelte 应用程序?

    如何让活动发挥作用?当然,我可以将方法作为道具传递并在独立应用程序中使用它,但如果可能的话,我宁愿调度/监听事件。

【问题讨论】:

【参考方案1】:
    有没有更好的方法来包含独立的 Svelte 应用程序?

App 和 Component 没有特别的区别。

<script>
const App1 = window.app1
</script>

<App1 prop1="one" prop2="two" />

可以工作,但这取决于应用程序是否使用相同的苗条运行时。 (取决于应用的捆绑方式)

您可能想尝试是否可以将应用程序生成为 lib 使用 svelte-kit package 命令。

    如何让活动发挥作用?

您可以向事件添加侦听器并分派这些事件:

const dispatch = createEventDispatcher()
cmp.$on('eventname', (event) => 
  dispatch('eventname', event);
);

这将使用 CustomEvent 包装原始事件。我还没有找到按原样发出事件的方法。而且 Svelte 没有像 Vue 那样的 $$listeners。所以你需要让 ComponentWrapper.svelte 知道要监听哪些事件。

像你建议的那样使用这些道具可能会更干净。

【讨论】:

cmp.$on 是我想要的,谢谢!至于应用程序和组件...app1 是由另一个开发人员编译的 Svelte 应用程序(main.js 基本上导入一个 Svelte 组件,然后将其设置为 window.app1;这是由 Svelte 编译成一个 bundle.js 加载为html 中的典型脚本),所以我不能将它用作我的应用程序中的组件,因为它需要被实例化,因此与包装组件共舞。

以上是关于如何将 Svelte 应用程序用作另一个 Svelte 应用程序中的组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将多个 .xib 重新用作另一个 .xib 的模板?

Angular:如何将组件用作路由条目和另一个组件的模板

如何在运行时将编译的 svelte-components/-apps 导入 svelte-app

如何将 Routify 与 Snowpack 和 Svelte 一起使用

如何将 Google Adsense 添加到 Svelte/Sapper 网络应用程序?

如何获取一个程序的输出并将其用作 C++ 上另一个程序的输入?