im looking to generate components based on input array of objects lets say:
let components = [
{ Hero: { componentData: {} },
{ AnotherComponent: { componentData: {} }
]
where 'Hero' and 'AnotherComponent' are component names that are used in import. all possible components are imported - i know in advance all components that could be used, i just dont know which will be used and in what order.
then i would like to do something like below pseudo-code as i know Object.keys(components)[0] is a string not a component class
{#each components as component}
<svelte:component this={Object.keys(components)[0]} data={component.componentData} />
{/each}
maybe there is a way to get a list of all imported components in svelte so i could map string names to components classes?
No, that's an interesting idea but you can't do string to component. For one thing, the name of variables, including the ones from imports, will very probably be lost when the code is minified for production.
// the Hero variable will probably become something like `a` after minify
import Hero from './Hero.svelte'
So you'd need to maintain a string => component map instead. Something like this:
import Hero from './Hero.svelte'
import OtherComponent from './OtherComponent.svelte'
// NOTE should survive minification 'cause object keys are strings
const components = {
Hero,
OtherComponent,
}
...
You could export this list from a components.js
file or something, to easily share it between consumers. If you do so, you could also leverage ES syntax to make your code a bit more terse:
components.js
export { default as Hero } from './Hero.svelte'
export { default as OtherComponent } from './OtherComponent.svelte'
Consumer.svelte
<script>
import * as components from './components.js'
export let cmp = 'Hero'
</script>
<svelte:component this={comoponents[cmp]} />
That being said, if you can skip the string mapping altogether (depends on where your source data comes from / how it is generated), you'll probably be able to get something more dynamic and easier to maintain in the long run.
<script>
import Hero from './Hero.svelte'
import OtherComponent from './OtherComponent.svelte'
const components = [
{ component: Hero, componentData: {} },
{ component: OtherComponent, componentData: {} },
]
</script>
<svelte:component this={components[0].component} />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With