svelte 从未知对象递归创建树视图

svelte recursively create treeview from unknown object

我正在编写某种原始 CMS,仅用于编辑、更新和添加应用程序的新字符串。 字符串都存储在数据库中,每个字符串都有一个特殊的键(代表项目“shared.atoms.copie...”的文件夹结构),用于从源代码到数据库的引用。 编辑内容等已经编码,但现在我需要为用户提供某种导航和查看正在编辑的页面预览的可能性,方法是单击(例如)导航节点

为此,我想构建一个已经从所有键构建的对象的树视图,如下所示:

tree: {
  common: {
    date: [{
      lang: "en", 
      key: "common.date", 
      version: 1, 
      value: "Date"
    },
    block: {
      lang: "en", 
      key: "common.block", 
      version: 3, 
      value: "Block"
    }]
  },
  shared: {
    atoms: {
      copyClipboard: {
        copiedToClipboard: [{
           lang: "en", 
           key: "shared.atoms.copyClipboard.copiedToClipboad", 
           version: 3, 
           value: "Copied to Clipboard!"
        }]
      }
    }
  }
}

在 javascript 我得到了这个解决方案当我使用 {@html htmlTree}:

时,它给了我一棵树
function buildHtmlTree(treeNode) {
  let objKeys = Object.keys(treeNode);
  if (objKeys.length == 0) {
    return;
  }
  for (let key of objKeys) {
    let currentNode = treeNode[key];
    htmlTree += `
      <ul class="ml-2 mb-4">
        <span>
          ${key}
        </span>
      `;
    if (Array.isArray(currentNode)) {
      // is leaf
      for (let currentLanguage of currentNode) {
        htmlTree += `
          <li class="ml-2">
            ${currentLanguage.lang}: ${currentLanguage.value}
          </li>
          `;
      }
    } else {
      // is branch
      buildHtmlTree(currentNode);
    }
    htmlTree += `</ul>`;
  }
}

buildHtmlTree(tree);

现在我正试图让它变得更苗条,但我被困在这个...我想我只是做了一个无限循环。

<script>
  let svelteTree = Object.keys(tree);
</script>

<section>
  {#each svelteTree as key}
    <ul class="ml-2 mb-4">
      <span>{key}</span>
      {#if Array.isArray(svelteTree[key])}
        {#each svelteTree[key] as currentLanguageSvelte}
          {currentLanguageSvelte.lang}: {currentLanguageSvelte.value}
        {/each}
      {:else}
        <svelte:self svelteTree={svelteTree[key]} />
      {/if}
    </ul>
  {/each}
</section>

如果values既不是Array也不是Object,你可以不调用svelte:self直接输出:

{#each Object.entries(data) as [key, values]}
 <ul class="ml-2 mb-4">
  <span>{key}:</span>
  {#if Array.isArray(values)}
    {#each values as item}
      <svelte:self data={item} />
    {/each}
  {:else if (typeof values === 'object')}
    <svelte:self data={values} />
  {:else}
    <span>{values}</span>
  {/if}
 </ul>
{/each}

Working example