在 svelte 中基于对象创建组件

create components based on object in svelte

我希望根据对象的输入数组生成组件让我们说:

let components = [
  { Hero: { componentData: {} },
  { AnotherComponent: { componentData: {} }
]

其中 'Hero' 和 'AnotherComponent' 是导入中使用的组件名称。 所有可能的组件都已导入 - 我事先知道可以使用的所有组件,我只是不知道将使用哪些组件以及以什么顺序使用。

然后我想做如下的事情 伪代码 据我所知 Object.keys(components)[0] 是一个字符串而不是一个组件 class

{#each components as component}
  <svelte:component this={Object.keys(components)[0]} data={component.componentData} />
{/each}

也许有一种方法可以在 svelte 中获取所有导入组件的列表,这样我就可以将字符串名称映射到组件 classes?

不,这是一个有趣的想法,但您不能将字符串转换为组件。一方面,变量的名称,包括来自导入的变量的名称,很可能会在代码被缩小以用于生产时丢失。

// the Hero variable will probably become something like `a` after minify
import Hero from './Hero.svelte'

因此您需要维护一个字符串 => 组件映射。像这样:

import Hero from './Hero.svelte'
import OtherComponent from './OtherComponent.svelte'

// NOTE should survive minification 'cause object keys are strings
const components = {
  Hero,
  OtherComponent,
}

...

您可以从 components.js 文件或其他文件中导出此列表,以便在消费者之间轻松共享。如果这样做,您还可以利用 ES 语法使您的代码更简洁:

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

也就是说,如果您可以完全跳过字符串映射(取决于源数据的来源/生成方式),您可能能够在长 运行.

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