Svelte 5中如何用{@render}替换嵌套组件中已弃用的<slot />?
Svelte 5中如何用{@render}替换嵌套组件中已弃用的?
嘿,我刚搞定了Svelte 5里替换<slot />的类似场景,正好和你的递归列表需求对上!我来一步步给你讲怎么改:
首先得明白Svelte 5的核心变化:原来的<slot />被废弃了,现在组件的内容(不管是默认slot还是命名slot)都要通过props传递,然后用{@render}语法来渲染。对于默认slot的内容,Svelte 5会自动把它封装成一个特殊的$children props,我们直接用{@render $children}就能替代原来的<slot />。
第一步:改造List.svelte
把原来的<slot />直接替换成{@render $children}就行,其他逻辑保持不变:
<script lang="ts"> import type { List } from 'datocms-structured-text-utils'; let { node }: { node: List } = $props(); let { style } = $state(node); </script> {#if style === 'numbered'} <!-- 用{@render $children}替代<slot /> --> <ol>{@render $children}</ol> {:else} <ul>{@render $children}</ul> {/if}
第二步:调整+page.svelte的用法
这里注意你代码里的<Component {node}>应该是笔误,实际应该是<List {node}>对吧?保持原来的递归逻辑不变就行,因为$children会自动接收标签内部的内容(也就是你用svelte:self渲染的子节点):
<List {node}> {#if hasChildren(node)} {#each node.children as child} <svelte:self node={child} /> {/each} {/if} </List>
额外说明(如果以后用命名slot)
要是你以后需要用命名slot,就不能依赖$children了,得显式定义props来接收:
比如在List.svelte里声明一个header props:
<script lang="ts"> // ... 其他代码 let { header } = $props(); </script> {@render header} {#if style === 'numbered'} <ol>{@render $children}</ol> {:else} <ul>{@render $children}</ul> {/if}
然后在父组件里传递:
<List {node} header={<h3>我的列表标题</h3>}> <!-- 默认slot内容 --> </List>
这样改完之后,你的递归列表就能和原来Svelte 4里的逻辑完全一致,同时符合Svelte 5的新语法规范啦!
备注:内容来源于stack exchange,提问作者Thomaszter
相关产品推荐
相关产品推荐

