You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte中使用svelte:self实现嵌套循环获取子数据的可行性

关于Svelte中递归渲染菜单的问题

问题描述

我想知道能不能用svelte:self来获取children.service1和children.sublinks,还是应该选择递归或多重循环的方式?另外我已经尝试了一种实现,但觉得可以优化。

原始数据

let mainMenuLinks = [
    {
        name: 'Services',
        link: '/services',
        children: [
            {
                service1: 'Auditng & Assurance',
                icon: 'fa fa-check',
                link: '/services/audit',
                caption: 'We provide a full range of audit and assurance services to a wide range of clients',
                sublinks: [
                    { name: 'Compliance Audit', link: '/services/audit/compliance' },
                    { name: 'Financial Audit', link: '/services/audit/financial' },
                ]
            },
            {
                service2: 'Taxation',
                icon: 'fa fa-calculator',
                link: '/services/taxation',
                caption: 'We provide a full range of audit and assurance services to a wide range of clients',
                sublinks: [
                    { name: 'Corporate Tax', link: '/services/taxation/corporate' },
                    { name: 'Individual Tax', link: '/services/taxation/individual' },
                ]
            }
        ]
    }
];

现有实现代码

<script>
    export let links;
</script>

{#each links as link}
    <h3>
        {link.name}
    </h3>
    {#each link.children as item, index}
        <h5>
            {item[`service${index+1}`]}
        </h5>

        {#each item.children as i}
            <p>
                {i.name}
            </p>
        {/each}
    {/each}
{/each}

解决方案

1. 先统一数据结构(关键优化点)

你的原始数据结构有个明显问题:子项用service1、service2这种动态键名,子链接用sublinks,和父级的name、children命名不统一,导致渲染时要动态拼接键名,既麻烦又容易出错。建议改成统一格式:

  • 所有层级的项都用name存标题
  • 子项列表统一用children命名(替换原来的sublinks)

修改后的数据:

let mainMenuLinks = [
    {
        name: 'Services',
        link: '/services',
        children: [
            {
                name: 'Auditng & Assurance',
                icon: 'fa fa-check',
                link: '/services/audit',
                caption: 'We provide a full range of audit and assurance services to a wide range of clients',
                children: [
                    { name: 'Compliance Audit', link: '/services/audit/compliance' },
                    { name: 'Financial Audit', link: '/services/audit/financial' },
                ]
            },
            {
                name: 'Taxation',
                icon: 'fa fa-calculator',
                link: '/services/taxation',
                caption: 'We provide a full range of tax services to a wide range of clients',
                children: [
                    { name: 'Corporate Tax', link: '/services/taxation/corporate' },
                    { name: 'Individual Tax', link: '/services/taxation/individual' },
                ]
            }
        ]
    }
];

2. 用svelte:self实现递归组件(最优方案)

svelte:self完全可行,而且是Svelte官方推荐的递归组件实现方式,比多重循环更优雅,能轻松处理任意层级的菜单,以后扩展层级也不用改组件代码。

创建一个Menu.svelte组件:

<script>
    export let items;
</script>

{#each items as item}
    <div class="menu-item">
        <!-- 渲染当前项的标题和链接 -->
        {#if item.link}
            <a href={item.link} class="menu-link">
                {#if item.icon}
                    <i class={item.icon}></i>
                {/if}
                {item.name}
            </a>
        {:else}
            <span class="menu-title">{item.name}</span>
        {/if}

        <!-- 如果有子项,递归渲染 -->
        {#if item.children && item.children.length > 0}
            <div class="submenu">
                <svelte:self items={item.children} />
            </div>
        {/if}
    </div>
{/each}

3. 使用组件

在父组件中引入并使用这个菜单组件:

<script>
    import Menu from './Menu.svelte';
    let mainMenuLinks = [/* 上面修改后的数据 */];
</script>

<Menu items={mainMenuLinks} />

为什么这比多重循环好?

  • 代码更简洁,逻辑清晰,避免了多层嵌套的{#each}循环
  • 支持任意层级的菜单扩展,不用因为加了新层级而修改组件
  • 数据结构统一后,维护成本更低,不容易出现键名拼接错误

如果实在不想修改原始数据结构,也可以用svelte:self,但需要在组件里处理动态键名(比如取item[Object.keys(item).find(k => k.startsWith('service'))]来获取标题,把sublinks作为子项),但这种方式不推荐,因为数据结构不规范会增加后续维护的复杂度。

内容的提问来源于stack exchange,提问作者jeff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:40:25