簡體   English   中英

如何在 Svelte 中使用開關渲染組件?

[英]How do I render components with a switch in Svelte?

我想在 Svelte 中使用switch case語句有條件地呈現組件,如下所示:

// index.svelte

<script>
import TextContent from './components/text-content.svelte'
import { someData } from './api/some-data.js'


    const ContentSwitch = (data) => {
        switch (data._type) {
            case 'block':
                return data.children.map((child) => ContentSwitch(child));
            case 'span':
                return (
                    <TextContent>
                        <span slot="text-content">{data.text}</span>
                    </TextContent>
                );
        }
        for (let index = 0; index < data.length; index++) {
            return data.map((item) => ContentSwitch(item));
        }
    };

</script>

<div>
    {#each someData as data}
        {ContentSwitch(data)}
    {/each}
</div>

文本內容組件:

// components/text-content.svelte

<slot name="text-content">
    <span />
</slot>

似乎這種方法在 Svelte 中不起作用,因為我收到了Unexpected Token錯誤。

在 Svelte 中可以使用開關渲染組件嗎?

我認為在 (java)script 標簽內的 switch 'span' 中返回 html 語法不能像這樣工作。
實際上,這不是不同組件之間的切換,而是在 TextContent 組件內呈現不同的嵌套“data.text”字段?

someData的結構是什么? 假設它看起來像這樣

let someData = [
{
  _type: 'block',
  children: [{
  _type: 'span',
  text: 'textValue#1'
  }]
},
{
  _type: 'span',
  text: 'textValue#2'
}
]

遞歸函數可用於獲取所有嵌套的文本字段

    function getSpanTexts(dataArr) {
        return dataArr.flatMap(data => {
            switch (data._type) {
            case 'block':
                return getSpanTexts(data.children)
            case 'span':
                return data.text                
        }
        })
    }
    
    $: textArr = getSpanTexts(someData)  // ['textValue#1', 'textValue#2']

然后可以使用 html 中的 each 循環來迭代文本字段,每個循環都在 TextContent 組件中呈現

<div>
    {#each textArr as text}
         <TextContent>
             <span slot="text-content">{text}</span>
         </TextContent>
    {/each}
</div>

查看代碼片段的這個工作 REPL

你在那里寫的東西更像是用於 React 的 JSX。 在 Svelte 中,您不會在 JavaScript 中編寫 HTML,而是將它們分開。

您要做的是制作一個查找表並使用 svelte:component 來呈現正確的組件:

<script>
  const BlockTypes = {
    "span": TextContent
  }
</script>

{#each children as child}
  {#if child.type === 'block'}
    <svelte:self {...child} />
  {:else}
    <svelte:component this={BlockTypes[child.type]} {...child} />
  {/if}
{/each}

svelte:self是假設,這本身也是塊類型的元素,其原因不能導入一個組件插入到自己,所以你在這里需要這種特殊情況下。 有了這個,你就可以開箱即用地嵌套塊。

在此示例中,您將子項的所有屬性傳遞給渲染的組件,因此您必須稍微重寫您的組件,您也可以使用插槽,但這會導致命名插槽的嚴重混亂。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM