Docusフレームワークで階層データを表示するための再帰コンポーネントの実装

DocusはNuxtとMarkdownを使用してビューティフルなドキュメンテーションを作成できるツールです。この記事では、Docusのフロントエンドコンポーネントを使って階層データを表示する方法を紹介します。

再帰コンポーネントとは?

再帰コンポーネントは、自分自身をテンプレート内で呼び出すことができるコンポーネントです。これはファイル構造やナビゲーションメニューなど、階層的なデータを表示するのに適しています。

Docusでの階層データの処理

Docusプロジェクトのlayer/app/app.vueファイルには、ナビゲーションデータから階層構造を抽出するサンプルコードがあります。

const { data: navData } = await useAsyncData(() => `nav_${collectionName.value}`, () => fetchNav(collectionName.value), {
  transform: (data) => {
    const root = data.find(item => item.path === '/docs')?.children ?? data;
    return root.find(item => item.path === `/${locale.value}`)?.children ?? root;
  },
  watch: [locale],
});

このコードは、特定の言語のナビゲーションツリーを抽出し、後の表示に使用します。

再帰コンポーネントの基本的な実装手順

1. コンポーネントの定義

再帰コンポーネントを定義するには、テンプレート内で自分自身を参照する必要があります。

<template>
  <div class="tree-item">
    <div class="item-content">
      {{ item.label }}
    </div>
    <div v-if="item.children && item.children.length" class="sub-items">
      <TreeItem v-for="child in item.children" :key="child.id" :item="child" />
    </div>
  </div>
</template>

<script setup>
const props = defineProps({
  item: {
    type: Object,
    required: true
  }
})
</script>

2. 階層データの処理

以下のコードは、APIからデータを取得して階層構造に変換する例です。

const { data: navData } = await useAsyncData(`nav_${collectionName.value}`, () => fetchNav(collectionName.value), {
  transform: (data) => {
    const root = data.find(item => item.path === '/docs')?.children ?? data;
    return root.find(item => item.path === `/${locale.value}`)?.children ?? root;
  },
  watch: [locale],
});

3. 再帰コンポーネントのレンダリング

親コンポーネントで再帰コンポーネントを使用する方法は以下の通りです。

<template>
  <div class="tree-root">
    <TreeItem v-for="node in navData" :key="node.id" :item="node" />
  </div>
</template>

<script setup>
const { data: navData } = await useAsyncData('nav', () => getNavData())
</script>

Docusでの実際の利用例

Docusのナビゲーションメニューは典型的な階層構造の使用例です。再帰コンポーネントにより、複数レベルのメニューを表示できます。

再帰コンポーネントのパフォーマンス最適化

  • v-memoを使用したレンダリングの最適化: 静的なノードに対してv-memoを使用して不要な再レンダリングを減らす
  • 遅延読み込み: 大規模なツリー構造の場合、必要な部分のみを読み込む
  • 仮想スクロール: 超大規模なツリー構造の場合、表示領域のみをレンダリングする

タグ: Nuxt docus Vue recursive-component tree-structure

6月29日 21:33 投稿