Reputation: 9100
Use case: I have a couple of Svelte components that are compiled as a standard Svelte app (i.e., not a web component) that are then used to enhance the functionality of the main Svelte app.
I am instantiating them using the typical app = new SvelteApp({target, props})
method through a wrapper/proxy component (as suggested in this answer), so that I can do something like this:
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} />
This works fine except that I can't listen to events dispatched by the App1 and App2 using the on:event={}
directive on the ComponentWrapper
or the div
element inside it.
My questions are:
Is there a better way to include standalone Svelte apps?
How would I make events work? Sure, I can pass a method as a prop and use that inside the standalone apps, but I would rather dispatch/listen to events if that's at all possible.
Upvotes: 1
Views: 1185
Reputation: 29917
There is no special difference between an App and a Component.
<script>
const App1 = window.app1
</script>
<App1 prop1="one" prop2="two" />
could work, but that depends if the App uses the same svelte runtime. (Depends on how the apps are bundled)
You might want to try if you could generate the App as lib using @sveltejs/package command.
You can add listeners to the events and dispatch these:
const dispatch = createEventDispatcher()
cmp.$on('eventname', (event) => {
dispatch('eventname', event);
});
This wraps the original event with a CustomEvent. I haven't found a way to emit an event as-is. And Svelte doesn't have a $$listeners
like Vue. So you need to let the ComponentWrapper.svelte know what events to listen for.
Using props for these like you suggested might be cleaner.
Upvotes: 2