Svelte offers remarkable flexibility for creating dynamic components.
In this tutorial, we'll explore how to instantiate components on the fly
and pass properties to them in an elegant and efficient manner.
Basics of Dynamic Components
<script>
import Foo from "./Foo.svelte";
import Bar from "./Bar.svelte";
let actual = Foo;
</script>
<svelte:component this={actual} on:click={()=>actual=Bar} />
In this simple example, we import two components: Foo and Bar.
We create a variable actual
where we'll place the current component, in this case Foo
.
Svelte offers a special <svelte:component>
tag that allows creating components on the fly.
We specify in the this
property which component to display, in our example, actual
.
For demonstration, we add an on:click
event to change the component to Bar
by simply modifying the actual
variable.
Svelte takes care of displaying the component by substituting Bar
for Foo
.
Passing Parameters (props)
A key point is the ability to pass parameters to dynamic components. For a classic component, you can write:
<Foo age=22 />
We assign the value 22 to the age
property.
For a dynamic component, it's the same:
<svelte:component this={Foo} age=22 />
But let's imagine our second component Bar
accepts 2 parameters:
<Bar age=572 name="Da Vinci" />
Our dynamic component should be written as:
<svelte:component this={Bar} age=572 name="Da Vinci" />
And there, we have a problem. How to manage them in the dynamic component while passing the right number of parameters?
My technique involves encapsulating the component with its properties in an object and using the spread operator
{...props}
.
For example, for the Foo
component, I would write an object FooCmp
:
<script>
let FooCmp = {
cmp: Foo,
props: {
age: 42
}
}
let actual = FooCmp;
</script>
<svelte:component
this={actual.cmp}
{...actual.props}
/>
Here's the complete example, using the 2 components and a
flip
function to interchange them.
App.svelte
<script>
import Foo from "./Foo.svelte";
import Bar from "./Bar.svelte";
let FooCmp = {
cmp: Foo,
props: {
age: 42
}
};
let BarCmp = {
cmp: Bar,
props: {
age: 572,
name: "Da Vinci"
}
};
let actual = FooCmp;
let flip = () => actual = actual.cmp == Foo ? BarCmp : FooCmp;
</script>
<svelte:component
this={actual.cmp}
on:click={flip}
{...actual.props}
/>
Each imported component will display its properties in a button and activate the on:click
event.
Foo.svelte
<script>
export let age = 0;
</script>
<button on:click>Foo {age}</button>
Bar.svelte
<script>
export let name = "";
export let age = 0;
</script>
<button on:click>Bar {name} {age}</button>
Note that we only pass through the on:click
event as it is not processed here, but at the level of the parent, the dynamic component.
Conclusion
You can easily instantiate and manipulate components on the fly with <svelte:component>
. Svelte offers a simple and powerful approach to creating dynamic components.
And JavaScript provides us with all the tools to work around the problem of different numbers of props per component.
Don't hesitate to experiment and adapt this approach to your own needs!
Top comments (0)