如何继承带有苗条组件的插槽?
Posted
技术标签:
【中文标题】如何继承带有苗条组件的插槽?【英文标题】:How to inherit slots with svelte components? 【发布时间】:2022-01-23 19:00:11 【问题描述】:有一个组件<Bar>
继承自组件<Foo>
。
<Foo>
组件定义了一个名为 content
的插槽,其中包含备用内容。 <Bar>
组件还定义了一个名为 content
的插槽,具有不同的后备内容。
<!-- Foo.svelte -->
<slot name="content">
foo fallback
</slot>
<!-- Bar.svelte -->
<script>import Foo from './Foo.svelte'</script>
<Foo>
<span slot="content">
bar fallback
</span>
</Foo>
<Bar>
组件在使用 <Foo/>
调用时显示回退,但在使用 <Bar><span slot="content">bar custom</span></Bar>
调用时不显示自定义内容。
你能告诉我我做错了什么吗?
<Foo/>
<!-- prints 'foo fallback': OK -->
<Foo>
<span slot="content">foo custom</span>
</Foo>
<!-- prints 'foo custom': OK -->
<Bar/>
<!-- prints 'bar fallback': OK -->
<Bar>
<span slot="content">bar custom</span>
</Bar>
<!-- prints 'bar fallback': KO - I would have expected 'bar custom' -->
请注意,这段代码过于简单,我的实际用例比这要复杂一些,我需要在那里使用插槽。
小提琴:https://svelte.dev/repl/5c525651eb8b4f60a6a696c1bd19f723
【问题讨论】:
你没有为Bar
定义一个槽,所以所有渲染的都是Foo
的槽。更清晰的方法是为Bar
repl定义一个属性
谢谢。这是一个过于简化的代码示例,用于暴露我的问题,在我的实际用例中,一个属性不够强大,我确实需要使用插槽。
很公平,尽管您还不清楚您希望嵌套插槽如何工作。无论如何,您将插槽内容传递给 Bar
但 Bar 没有定义插槽,这是一个选项,它仍然在 Foo
内呈现传递给 Bar
的插槽内容:REPL(看起来 REPL 站点已损坏)
【参考方案1】:
您似乎想在Foo
定义的槽中渲染传递给Bar
的槽内容,但目前您还没有在Bar
中定义槽,因此无处可使用传递的内容,因此后备值总是传递给Foo
。
解决方案可能类似于以下内容,在Bar
中定义一个content
插槽在传递给Foo
的内容插槽的范围内。
// App.svelte
<script>
import Foo from './Foo.svelte'
import Bar from './Bar.svelte'
</script>
Expected: <em>bar custom</em><br>
<Bar>
<span slot="content">bar custom</span>
</Bar>
// ./Bar.svelte
<script>
import Foo from './Foo.svelte';
</script>
<Foo>
<span slot="content">
<slot name="content">bar fallback</slot>
</span>
</Foo>
// ./Foo.svelte
<slot name="content">
foo fallback
</slot>
REPL
【讨论】:
谢谢。这看起来不错,但这会与第三级继承中断。例如,使用从<Bar>
继承的 <Baz>
组件并且没有后备插槽,我无法实现使用自定义内容。 svelte.dev/repl/58c4dadc8d884abd8c46e4f8edfa6ea3 虽然,这可能是另一个问题。
好吧,您刚刚复制了Foo
Bar
继承中的问题,方法是未在Baz
中指定插槽。如果没有更多关于你的真实组件如何交互的背景信息,我真的无法提供更多。【参考方案2】:
我认为大多数答案都非常接近。我相信您可以通过创建一个内容和名称具有相同值的插槽来修复它。以您的示例 (Repl with full 3rd level inheritance) 为基础,
<!-- Foo.svelte -->
<slot name="content">
foo fallback
</slot>
<!-- Bar.svelte -->
<script>import Foo from './Foo.svelte'</script>
<Foo>
<slot name="content" slot="content">
bar fallback
</slot>
</Foo>
通过这种方式,我们既可以通过插槽,也可以包含我们的新后备。
如果您希望确保 span 存在,可以根据您的用例将其放在 slot
内部或外部来完成。
<!-- Bar.svelte -->
<script>import Foo from './Foo.svelte'</script>
<!-- option 1-->
<Foo>
<span>
<slot name="content" slot="content">
bar fallback
</slot>
</span>
</Foo>
<!-- option 2-->
<Foo>
<slot name="content" slot="content">
<span>
bar fallback
</span>
</slot>
</Foo>
【讨论】:
以上是关于如何继承带有苗条组件的插槽?的主要内容,如果未能解决你的问题,请参考以下文章
Vue-七七创建全局组件——“Loading“ 使用extend创建组件——弹出层 单继承:vue组件间的继承。——继承js的部分 异步组件加载 异步组件工厂 组件插槽