在 @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>

那么,我怎样才能将 &lt;slot&gt;&lt;/slot&gt; 包裹在 @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 中使用插槽的主要内容,如果未能解决你的问题,请参考以下文章

在Vue中使用插槽

v-solt 插槽(基础使用具名插槽作用域插槽等)

使用渲染功能时如何在 Vue.js 模板中定义插槽?

Vue组件高级 插槽的使用slot

vue中插槽上手使用

Vue 作用域插槽