「Nuxtでプログを構築しよう!!」の6回目。今回は、記事の一覧を表示してみよう。
「Nuxt でプログを構築しよう!!」の 6 回目。今回は登録した記事の一覧を表示する画面を作りたいと思います。Mardown ファイルで登録した記事を検索して一覧表示したいと思います。予習としてCreate a Blog with Nuxt Contentやnuxt/contentを読んでおきましょう。ほとんどはこれだけで実装方法がわかります。
記事の登録
記事一覧を表示するためのダミー記事を登録します。
(1)フロントマター
記事のヘッドに以下のように共通の項目を入れました。---の間に YAML の形式で記載するようです。今回は記事のタイトル、記事の概要、タグ、記事のイメージ画面としました。
---
title: 'titlexx'
description: 'descriptionxx'
group: software
tags: [Nuxt]
img: xxx.jpg
---
(2)記事
記事の書き方は、basic syntax guideを参考にすれば良いでしょう。今回はダミーの記事を登録していきます。
(3)記事の登録
作成した記事を/content/articles/ja/article01.md、article02.md、article03.md、article04.md、article05.md と登録しました。 記事の見出し画像も適当な画像を/static/images/blog01.webp みたいに登録しておきます。言語切り替えることを考えてますので、日本語の記事は、ja フォルダの下に登録して、英語の記事は、en フォルダに登録したいと思います。
---
title: 'title01'
description: 'description01'
group: software
tags: [nuxt]
img: blog01.jpg
---
xxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
記事の一覧を表示する Articles コンポーネントの作成
記事の一覧を表示するコンポーネントを作成したいと思います。このコンポーネントの機能を整理したいと思います。検索したいフォルダーをキーに該当する context フォルダーの記事一覧を検索する。検索した一覧を元に画面に一覧表示する。
検索したいキーは、props として受け取ります。このキーにより content のどのフォルダーを検索するか切り換えできるようにします。キーが’articles’の場合はブログの記事を検索します。検索する記事がない場合はエラーメッセージを表示します。
また最終的には、記事に設定されたタグや言語に応じた記事も検索できるようにしたいと思いますが今回は単純に該当フォルダの記事を一覧表示することにします。
(1)html
articles オブジェクトから 1 件ごとに articles オプジェクトを取り出してリンク先とタイトルを表示します。
<template>
<div class="posts">
<img class="blog-img" :src="img" />
<div class="article-list">
<div v-for="article of articles" :key="article.slug">
<NuxtLink
:to="{ name: 'blog-slug', params: { slug: article.slug } }"
>
{{ article.title }}
</NuxtLink>
</div>
</div>
</div>
</div>
</template>
Tip NuxtLinkタグでリンク先を’blog-slug’、パラメータをarticle.slugと定義しています。このように定義するとリンク先は、/blog/xxxx となり、この xxx には article.slug の値が設定されます。article.slug には記事のファイル名が登録されていますので、/contet/article/jp/article01.md ファイルの場合、/blog/article01 とリンク先がなります。
(2)typescirpt
こちらが記事を検索するスクリプトです。props の target をキーに記事一覧を検索します。
<script lang="ts">
import { defineComponent, reactive, computed, useContext } from 'nuxt-composition-api';
type Props = {
target: string;
img: string;
};
export default defineComponent({
props: {
target: String,
img: String,
},
setup(props: Props) {
const state = reactive<{
articles: [Object];
}>({
articles: [{}],
});
const articles = computed(() => state.articles);
// @ts-ignore
const { $content } = useContext();
// dummy stub
const lang = 'ja';
const tag = 'all';
searchTagArticles(props.target, lang, tag);
async function getArticles(target: string, lang: string, tag: string) {
let whereObj = {};
if (tag !== 'all') {
whereObj = '{ tags: { $contains: tag } }';
}
state.articles = await $content(target, lang)
.only(['title', 'description', 'img', 'slug', 'createdAt'])
.where(whereObj)
.sortBy('createdAt', 'desc')
.fetch();
}
return { articles };
},
});
</script>
Tip /content/articles/jaのフォルダ内を検索する時は、articles = await $content(‘articles’,‘ja’)で検索できます。$contentはsetupの引数とてcontextを引数として受け取る方式もありますが、今回は、useContextを利用していいます。const {$content} = useContext()
(3)css
こちらはイメージ画面を固定で表示しているスタイルシートです。画像ファイルの高さに依存しないように高さ固定で表示させてます。
<style>
.blog-img {
height: auto;
width: 100%;
height: 280px;
object-fit: cover;
}
</style>
index.vue の修正
プログのルートページの index.vue を修正します。/content/articles に登録している記事を一覧表示させたいので Articles のコンポーネントに引数を設定したいと思います。
<template>
<Articles />
</template>
<template>
<ArticleList :target="target" :img="img" />
</template>
<script lang="ts">
import { defineComponent } from 'nuxt-composition-api';
export default defineComponent({
setup() {
const target = 'articles';
const img = '/images/blog01.webp';
return { target, img };
},
});
</script>
検証
VSCode から実行をしてみます。記事一覧が表示されたら成功です。もし表示されなければ、記事登録のフォルダ名を確認してみてください。記事登録場所は、/content/articles/ja/article01.md となっています。
リンク先をクリックしても該当ページは表示されません。まだリンク先のページを作っていないためです。次回は、リンク先をクリックすると記事を表示てできるようにしたいと思います。