記事データObjの path からカテゴリーを判別し tampファイルに書き出す処理を追加
別ファイル func/methods.ts に 記事カテゴリー名のユニークな配列を生成してリターンする関数を追加
// docs/.vuepress/func/methods.ts
// ...
// 記事カテゴリー名のユニークな配列を生成してリターン
export const createUniqueCategoryNames = (articles: ArticleData[]) :string[] => {
// null を含む 記事カテゴリー名のユニークな配列
let uniqueCategoryNames: string[] = [...new Set(articles.map(obj => obj.category))] // exp.. [ 'vuePress', 'typeScript', null ]
// null を除外した記事カテゴリー名のユニークな配列をリターン
return uniqueCategoryNames.filter(category => category); // [ 'vuePress', 'typeScript' ]
};
onInitialized フックに関数 "createUniqueCategoryNames" を使って、記事カテゴリー名のユニークな配列を生成し、ループ処理で各カテゴリーごとの記事データ 配列Objを一時的ファイルとして書き出す処理を追加
// docs/.vuepress/config.ts
// ...
// 別ファイル 関数インポート
import { createPageObj, createFixedExtractArticles, createUniqueCategoryNames } from './func/methods'
export default defineUserConfig({
// ...
// onInitialized フック VuePressアプリが初期化された時点で呼び出される https://vuepress.github.io/reference/plugin-api.html#lifecycle-hooks
onInitialized: (app) => {
// ....
// 各記事データObjの frontmatter.lastUpdatedAt を 文字列(exp '2022-01-01') に変更した配列を生成
const extractArticlesData: ArticleData[] = createFixedExtractArticles(extractArticles);
// 👉 カテゴリーページ用に 各カテゴリ別 記事Objの配列を .vuepress/.cache/.temp フォルダに 一時的ファイル "category-{カテゴリー名}.js" として書き出し
// 記事カテゴリー名のユニークな配列
const uniqueCategoryNames = createUniqueCategoryNames(extractArticlesData);
// 各カテゴリー ごとにループ
uniqueCategoryNames.forEach(categoryName => {
// カテゴリーが一致する記事データの配列
const filteredCategoryPost = extractArticlesData.filter(obj => obj.category === categoryName);
// app.writeTemp() で 一時的ファイル "category-{カテゴリー名}.js" を書き出し
app.writeTemp(`category-${categoryName}.js`, `export const categoryPosts = ${JSON.stringify(filteredCategoryPost)}`)
});
},
})
書き出された 一時的ファイル "category-{カテゴリー名}.js" の中身 サンプル
export const categoryPosts = [
{
key: "v-xxkm06b0",
path: "/articles/vuePress/setting-up.html",
category: "vuePress",
frontmatter: {
title: "VuePress セットアップ ~ テーマ & マークダウン 設定",
description: "VuePress の基本設定(カスタマイズ)",
lastUpdatedAt: "2022-02-10T00:00:00.000Z",
image: "abc.svg",
},
links: [],
slug: "setting-up",
},
// {...}
// ...
];
カテゴリーページ docs/articles/{カテゴリー}/README.md を追加
カテゴリーページ docs/articles/{カテゴリー}/README.md ファイルを作成し、.mdファイル内の script で、一時的ファイルから該当カテゴリーの記事データObjの配列をインポート
<!-- docs/articles/vuePress/README.md -->
## カテゴリー "vuePress" の記事一覧
<ul>
<li v-for="pageData in categoryPosts">
<RouterLink :to="pageData.path">{{ pageData.frontmatter.title }}</RouterLink>
更新: {{ pageData.frontmatter.lastUpdatedAt.split('T')[0] }}
</li>
</ul>
<script setup lang="ts">
// 一時的ファイル docs/.vuepress/.temp/category-vuePress.js から記事データObjの配列をインポート
import { categoryPosts } from '@temp/category-vuePress'
</script>
表示例
- VuePress に Umami アナリティクスをセットアップ 更新: 2022-5-20
- 検索バーをヘッダー ナビバー(navbar)に追加 更新: 2022-5-18
- VuePress デフォルトテーマのカスタマイズ(子テーマで拡張) 更新: 2022-5-5
- VuePress カテゴリーページを追加 更新: 2022-4-26
- VuePress Client API メソッド 更新: 2022-4-26
- VuePress TOPページに記事一覧データを取得して表示 更新: 2022-4-25
- VuePress セットアップ ~ テーマ & マークダウン 設定 更新: 2022-4-25
- VuePress で Windi CSS (Tailwind) を利用できるように設定 更新: 2022-4-25
カードコンポーネントを作成し、カテゴリー記事一覧をカードで表示
リスト形式のテキストリンクでも特に問題ないが、せっかくなので Windi CSS (Tailwind)を利用したカードコンポーネント "CategoryPostsCard.vue" を作成し、カテゴリーページ '/articles/{カテゴリー名}/README.md' で記事一覧リンクをカードで表示するように設定してみる
Windi CSS (Tailwind)を利用したカードコンポーネント "CategoryPostsCard.vue" を作成
props として受け取ったカテゴリー記事データの配列Obj "categoryPosts" から記事の数だけループ処理でカードテキストリンクを表示するコンポーネント
<script setup> 構文のpropsをTypeScriptで定義
// docs/.vuepress/components/CategoryPostsCard.vue
// カテゴリーページ '/articles/{カテゴリー名}/README.md' でカテゴリー記事一覧をカードで表示するコンポーネント
<script setup lang="ts">
import 'virtual:windi.css'
import { ArticleData } from '../type' // 型エイリアス (type alias)
// https://zenn.dev/azukiazusa/articles/676d88675e4e74#props-%E3%81%A8-emit
interface Props {
categoryPosts: ArticleData[];
}
const props = defineProps<Props>();
// script 内で propsで受け取った値 categoryPosts にアクセスするには props.categoryPosts とする必要あり
// console.log("🚀 ~ file: CategoryPostsCard.vue ~ line 21 ~ props.categoryPosts", props.categoryPosts);
</script>
<template>
<div v-if="props.categoryPosts" class="py-3">
<div v-for="(postObj, index) in props.categoryPosts" :key="index"
class=" bg-gray-50 hover:bg-gray-100 dark:(bg-gray-800 hover:bg-gray-700) py-1 mx-auto my-2 rounded"
>
<div class="flex items-center mx-1">
<!-- 更新日 -->
<div class=" mx-1 w-1/7 min-w-60px rounded-2xl sm:mx-2">
<div class="px-2 text-xs font-semibold tracking-wide text-center ">
<span class=""> {{ postObj.frontmatter.lastUpdatedAt.split('T')[0] }} </span>
</div>
</div>
<!-- 記事タイトル -->
<div class="my-1 text-base font-extrabold leading-snug sm:(text-lg my-2)">
<!-- VuePress で Windi CSS (Tailwind) を利用できるように設定 -->
<RouterLink :to="postObj.path">
{{ postObj.frontmatter.title }}
</RouterLink>
</div>
</div>
</div>
</div>
</template>
props で カテゴリー記事データの配列を渡してカードコンポーネントで表示
- カテゴリーページ '/articles/{カテゴリー名}/README.md'ファイルの script で、一時的ファイルから該当するカテゴリーの記事データObjの配列をインポート
- カードコンポーネント "CategoryPostsCard" に props "categoryPosts" で渡す
<!-- docs/articles/vuePress/README.md -->
## カテゴリー "vuePress" の記事一覧
<CategoryPostsCard :categoryPosts="categoryPosts" />
<script setup lang="ts">
// 一時的ファイル docs/.vuepress/.temp/category-vuePress.js から記事データObjの配列をインポート
import { categoryPosts } from '@temp/category-vuePress'
</script>
