Sapper/Svelte - 需要包含@html 的内容来调用组件

问题描述

我正在使用 sapper 构建一个站点,该站点对单个博客条目使用 [slug].svelte 约定。博客内容来自(模拟)数据库,包含 html。

html 包含在底部,如下所示:

...
<div class="content">
  {@html post.html}
</div>
...

一切都很好,它呈现的 html 只是桃色。

但是,请考虑以下事项:

[slug].svelte 文件中:

import AComponent from '../../components/AComponent.svelte'

而且,在 {@html post.html} 中呈现的包含的 html 中:

<p>yada yada yada</p>
<AComponent prop="data" />
<p>More yada yada yada...</p>

AComponent 不会被实例化或调用

有什么办法可以做到这一点吗?还是我试图做一些不可能的事情?

(我知道该组件没问题 - 它已在另一个具有完整 html 的文件中进行了测试。)

谢谢

解决方法

我认为仅使用 @html 指令是不可能的。

来自the docs

表达式应该是有效的独立 HTML — {@html "<div>"}content{@html "</div>"} 将不起作用,因为不是有效的 HTML。

由于 <AComponent prop="data" /> 是一个 Svelte 组件而不是独立的 HTML,因此在使用 @html 时它不会实例化自身。

但是,您可以组合使用 <svelte:component> 来从字符串内容动态呈现组件的解决方案。

这是 Svelte REPL 中的概念的快速证明。有一堆边缘情况未被发现,但它表明这是可能的。我也粘贴了下面的代码。

<script>
    import ComponentA from './ComponentA.svelte';
    import ComponentB from './ComponentB.svelte';
    
    let raw = `<p>yada yada yada</p>
<ComponentA name="testing" />
<p>More yada yada yada...</p>`;
    
    $: rawLines = raw.split('\n');
    
    function getComponent(line) {
        const componentName = line.split(' ')[0].substring(1);
        switch (componentName) {
            case 'ComponentA':
                return ComponentA;
            case 'ComponentB':
                return ComponentB;
        }
        return null;
    }
    
    function getComponentProps(line) {
        const props = line.split(' ').slice(1,-1);
        const kvPairs = props.map(p => p.replaceAll('"','').split('='));
        return Object.fromEntries(kvPairs);
    }
</script>

<textarea bind:value={raw} />
{#each rawLines as line}
    {#if line[1] === line[1].toUpperCase()}
        <svelte:component this={getComponent(line)} {...getComponentProps(line)}></svelte:component>
    {:else}
        {@html line}
    {/if}
{/each}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...