# カテゴリー一覧を表示するVue.jsアプリの作成
2024-02-11 14:04:00
今回は、Vue.jsを使用して、カテゴリーごとに記事一覧を表示するアプリを作成します。具体的には、VuePressを使用してMarkdownファイルからカテゴリーを取得し、カテゴリーごとに記事一覧を表示します。
# 1. enhanceApp.jsの作成
まずは、VuePressのenhanceApp.jsを使用して、Markdownファイルからカテゴリーを取得する処理を行います。この処理は、Vueのmix-inを使用して全てのページで共通の処理を行います。
export default ({ Vue }) => {
Vue.mixin({
computed: {
categories() {
const categories = new Set();
this.$site.pages.forEach(page => {
if (page.frontmatter.category) {
categories.add(page.frontmatter.category);
}
});
return Array.from(categories);
}
}
});
};
このコードでは、全てのページのMarkdownファイルからカテゴリーを取得し、重複のない一意のカテゴリー一覧を作成しています。
# 2. Category.vueの作成
次に、カテゴリーごとに記事一覧を表示するVueコンポーネントを作成します。これには、Category.vueを使用します。
<template>
<div>
<div v-for="category in categories" :key="category">
<h3>{{ category }} の記事一覧</h3>
<ul>
<li v-for="post in filteredPosts(category)" :key="post.title">
<!-- post.title が存在する場合のみ表示 -->
<router-link v-if="post.frontmatter.title" :to="post.path">{{ post.frontmatter.title }}</router-link>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
categories: [],
};
},
computed: {
filteredPosts() {
return (category) => {
if (!this.$site || !this.$site.pages) {
return [];
}
return this.$site.pages
.filter(page => page.frontmatter.category === category && page.frontmatter.title)
.sort((a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date));
};
},
},
created() {
this.categories = this.$store.state.categories;
}
};
</script>
このコンポーネントでは、カテゴリーごとにフィルタリングされた記事一覧を表示する処理を行います。createdフック内でVuexストアからカテゴリーを取得しています。
# 3. Category.vue内で直接カテゴリーを定義したい場合
<template>
<div>
<div v-for="category in categories" :key="category">
<h3>{{ category }} の記事一覧</h3>
<ul>
<li v-for="post in filteredPosts(category)" :key="post.title">
<!-- post.title が存在する場合のみ表示 -->
<router-link v-if="post.frontmatter.title" :to="post.path">{{ post.frontmatter.title }}</router-link>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
categories: ["Vue.js", "React", "Angular"], // カテゴリーを直接定義
};
},
computed: {
filteredPosts() {
return (category) => {
if (!this.$site || !this.$site.pages) {
return [];
}
return this.$site.pages
.filter(page => page.frontmatter.category === category && page.frontmatter.title)
.sort((a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date));
};
},
},
};
</script>