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を使用して不要な再レンダリングを減らす
- 遅延読み込み: 大規模なツリー構造の場合、必要な部分のみを読み込む
- 仮想スクロール: 超大規模なツリー構造の場合、表示領域のみをレンダリングする