在 @html 中使用插槽
Posted
技术标签:
【中文标题】在 @html 中使用插槽【英文标题】:Using slots inside @html在 @html 中使用插槽 【发布时间】:2021-05-24 10:17:52 【问题描述】:在我的自定义组件中,我有一个来自 3rd 方库的 html 字符串(我对源代码具有写入权限)。我想把 <slot></slot>
放在那个 html 片段的正文中。
第 3 方库中的 html 字符串可能如下所示:
<div>
<!-- <slot></slot> is supposed to be here -->
</div>
MyComponent.svelte:
<script>
$: htmlString = lib.getHtmlFragment(/* optional body html*/);
</script>
@html htmlString
<!-- How do I put slots inside the htmlString -->
App.svelte:
<MyComponent>
<input bind:value />
</MyComponent>
那么,我怎样才能将 <slot></slot>
包裹在 @html htmlString
中而不会失去插槽的反应性?
【问题讨论】:
【参考方案1】:您可以在运行时搜索注入点,然后在此处创建组件,而不是注入插槽:
<script>
import onMount from 'svelte';
import MySlotComponent from './MySlotComponent.svelte';
export let html; // external html
let el;
onMount(() =>
let target = el.querySelector(...);
const cpn = new MySlotComponent( target );
return () => cpn.$destroy();
);
</script>
<div bind:this=el>
@html html
</div>
【讨论】:
【参考方案2】:这是不可能的,但那会很酷。我们可以通过 REPL 这样的虚拟数据来确认它失败了。
您可以将 onMount
中动态内容中具有特定 ID 的 div 替换为开槽内容,但您会失去像此 REPL 中所示的反应性,因为它在运行 @html 块后已经编译。
您可以设置一个点来分割动态内容,而不是将插槽内容复制到动态内容中,然后将其余的动态内容放在插槽内容之后,就像在这个REPL。在此示例中,我使用关键字来拆分 HTML 字符串,它只允许一个插槽,但如果输入由您通过源代码控制并且您只需要一个插槽,它确实保留反应性并允许可预测的结果.
或者您可以通过迭代拆分的 HTML 字符串的段并根据该段的内容呈现不同的组件,如REPL 所示,使用相同的想法创建一个迷你短代码模板语法。 .在这个示例中,我完全放弃了插槽,根据段的内容呈现不同的组件,并通过存储控制数据。使用此方法,您可以控制传递给组件的道具,并直接从 HTML 字符串中为您的内容和组件添加尽可能多的控制。
对于最后两个解决方案,请确保提供的动态内容周围没有包装父 div 标记。 Svelte 将始终强制单个 @html
标记本身是有效的 HTML,并且会在拆分这样的 HTML 字符串时关闭打开的标记,这会使您的标记无法用于 CSS/抓取/测试目的。
【讨论】:
感谢您的详尽回答。我在看着他们。以上是关于在 @html 中使用插槽的主要内容,如果未能解决你的问题,请参考以下文章