title | description | imgUrl | date | authors | tags | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Create a Blog with Nuxt Content 和訳 |
The Content module is a git files based headless CMS that provides powerful features when it comes to write blogs, documentation sites or just adding content to any regular website. In this post we will go through most of the benefits of this module and discover how we can create a blog with it. |
blog/creating-blog-with-nuxt-content/main.png |
2020-07-02 |
|
|
content module はgitファイルベースのヘッドレスCMSで、ブログやドキュメントサイトを書いたり、普通のウェブサイトにコンテンツを追加したりするときに強力な機能を提供します。この記事では、このmoduleの利点を見ていき、どのようにしてブログを作成できるのかを学んでいきます。
contentモジュールを使い始めるには、まずnpmかyarnを使ってモジュールをインストールする必要があります。
npm install @nuxt/content
// or
yarn add @nuxt/content
そして、nuxt.configファイル内のmodulesプロパティに追加します。
nuxt.config.js
export default {
modules: [
'@nuxt/content'
]
}
新しいプロジェクトを create nuxt-app
で作成した場合、contentモジュールを選んで追加できます。
contentモジュールは content/
ディレクトリのファイルを読み込むことで動作します。
mkdir content
プロジェクトを create nuxt-app
で作成した場合、content/
ディレクトリはすでに作成されています。
ブログの記事を追加できるarticles/
ディレクトリを作成してみましょう。
mkdir content/articles
contentモジュールは、markdown、csv、yaml、json、json5、またはxmlを解析できます。Markdownファイルを使って最初の記事を作ってみましょう。
最初の記事を作成してみましょう。
touch content/articles/my-first-blog-post.md
これでブログ記事のタイトルとテキストを追加できるようになりました。
# はじめてのブログ
contentモジュールを使用した私の最初のブログ記事へようこそ
markdownでは、#
を使用して<h1>
のタイトルを作成します。
それとブログタイトルとの間にスペースを残してください。markdownでの記述の詳細については、基本構文ガイドを参照してください。
ページ内にコンテンツを表示するには、ページの前にアンダースコア(_
)を付けて、動的ルーティングを使用します。ブログフォルダ内に_slug.vue
という名前のページコンポーネントを作成することで、vueルーターが提供するparams.slug
変数を使って各記事の名前を取得できます。
touch pages/blog/_slug.vue
ページがレンダリングされる前に記事の内容を取得するために、ページコンポーネントでasyncData
を使うことができます。変数$content
を使うことでcontextからコンテンツにアクセスできます。動的なページを取得したいので、params.slug
でどの記事を取得するかを知る必要があります。これは contextを通して利用可能です。
pages/blog/_slug.vue
<script>
export default {
async asyncData ({ $content, params }) {
// ここで記事を取得します
}
}
</script>
関数 asyncData
の内部では article
という名前の変数を作成し、await
に続いて $content
を使ってコンテンツを取得します。フェッチしたい内容を $content
に渡す必要があります。これは私たちの場合、記事のフォルダと、URLのパラメータから取得したslugです。そして、フェッチメソッドを最後までチェインして、フェッチの結果を含む記事を返します。
pages/blog/_slug.vue
<script>
export default {
async asyncData ({ $content, params }) {
const article = await $content('articles', params.slug).fetch()
return { article }
}
}
</script>
コンテンツを表示するために、document
propに返された変数を渡しつつ、 <nuxt-content />
コンポーネントを使用しています。この例では、よりセマンティックなHTMLとするために、HTMLのarticleタグでラップしていますが、お好みであればdivや他のHTMLタグを使用できます。
pages/blog/_slug.vue
<template>
<article>
<nuxt-content :document="article" />
</article>
</template>
これで、開発サーバーを実行して、ルート http://localhost:3000/blog/my-first-blog-post に行くことができ、マークダウンファイルからコンテンツを見ることができます。
nuxt/contentモジュールを使用すると、テンプレート内でアクセスしたり表示できるinjected variablesにアクセスできます。 ドキュメントのデフォルトinjected variablesを見てみましょう。
- body: bodyテキスト
- dir: ディレクトリ
- extension: ファイル拡張子 (今回の例では
.md
) - path: ファイルパス
- slug: ファイルslug
- toc: 目次のための配列
- createdAt: ファイル作成日
- updatedAt: ファイル更新日
先ほど作成した変数article
を使うことで、これらの変数にアクセスできます。article
は、私たちがアクセスできるこれらのさまざまな変数をすべて含んだオブジェクトです。<pre>
タグを使って出力することでそれらを調べてみましょう。
pages/blog/_slug.vue
<pre> {{ article }} </pre>
このページでは、空の配列である変数プロパティを持つオブジェクトと、h1タグとpタグ、その他の情報を持つbody変数があるとわかります。 下にスクロールしていくと、アクセスできる他のすべての変数があるとわかります。
"dir": "/articles",
"path": "/articles/my-first-blog-post",
"extension": ".md",
"slug": "my-first-blog-post",
"createdAt": "2020-06-22T10:58:51.640Z",
"updatedAt": "2020-06-22T10:59:27.863Z"
これは、変数articleに続いて私たちが使用したいものを使用することで、これらの変数にアクセスできることを意味します。たとえば、article.updatedAt
は私たちに投稿が最後に更新された日付を与えます。
pages/blog/_slug.vue
<p>記事の最終更新日: {{ article.updatedAt }}</p>
ご覧のように、date型そのままの出力は人間に優しいものではありません。日付を取得し、年、月、日のオプションを指定して新しい日付を返すメソッドを作成することで、これをフォーマットできます。
pages/blog/_slug.vue
methods: {
formatDate(date) {
const options = { year: 'numeric', month: 'long', day: 'numeric' }
return new Date(date).toLocaleDateString('en', options)
}
}
そして、テンプレートの中でformatDateメソッドを使用して、コンテンツから取得した日付を渡すと、きれいにフォーマットされた日付を返してくれます。
pages/blog/_slug.vue
<p>記事の最終更新日: {{ formatDate(article.updatedAt) }}</p>
YAMLフロントマターのブロックをmarkdownファイルに追加することで、カスタムしたinjected variablesを追加することもできます。それはファイルの最初にあり、---
の間に設定された有効なYAML形式でなければなりません。これは記事のタイトル、説明、画像などのSEO用変数を追加するのに便利です。
content/articles/my-first-blog-post.md
---
title: はじめてのブログ記事
description: ブログ作成のための@nuxt/contentの使い方を学ぶ
img: first-blog-post.jpg
alt: my first blog post
---
これで、title、description、img、alt変数を設定できたので、article
オブジェクト変数を使用してアクセスできます。
pages/blog/_slug.vue
<template>
<article>
<h1>{{ article.title }}</h1>
<p>{{ article.description }}</p>
<img :src="article.img" :alt="article.alt" />
<p>記事の最終更新日: {{ formatDate(article.updatedAt) }}</p>
<nuxt-content :document="article" />
</article>
</template>
このページを検査するとmarkdownの内部に書かれたすべてのものがnuxt-content
クラスを持つdivの内部にラップされていることがわかります。これは、nuxt-content
クラスでラップすることにより、markdownファイルから来るすべての要素に簡単にスタイルを追加できることを意味します。
pages/blog/_slug.vue
<style>
.nuxt-content h2 {
font-weight: bold;
font-size: 28px;
}
.nuxt-content h3 {
font-weight: bold;
font-size: 22px;
}
.nuxt-content p {
margin-bottom: 20px;
}
</style>
YAMLフロントマターから来る他のすべてのタグは、TailwindCSSを使用するか、スタイルタグにCSSを追加することで、通常通りのスタイルできます。
マークダウンタグは正しいタグに変換され、2つの <h1>
タグがあることを意味します。今、私たちのマークダウンファイルから1つを削除しなければなりません。
<h2>
タグの中には<a>
タグとhref
を持つ<a>
タグがあり、その中には icon
と icon-link
クラスを持つ span
タグがあることに注目してください。これはページのそのセクションへのリンクに便利です。現在、見出しのリンクは空で、かつ非表示になっています。スタイルを追加してみましょう。iconクラスを使って、アイコンの背景画像としてsvgを追加できます。まず、SVGをアセットフォルダーに追加する必要があります。この例では、svgフォルダーに追加したSteve Schoger's Hero Icons.のアイコンを使用しています。
pages/blog/_slug.vue
.icon.icon-link {
background-image: url('~assets/svg/icon-hashtag.svg');
display: inline-block;
width: 20px;
height: 20px;
background-size: 20px 20px;
}
自動生成されるtoc
変数は、ブログ記事に目次を追加することを可能にします。ブログ記事に見出しを追加してみましょう。
## This is a heading
This is some more info
## This is another heading
This is some more info
これで、これらの新しい見出しが toc
配列の中に、id、深さ、テキストを伴って表示されるようになりました。深さの値は見出しタグの値を参照するので、<h2>
の値は2、<h3>
の値は3となります。
content/articles/my-first-blog-post.md
## This is a heading
This is some more info
### This is a sub heading
This is some more info
### This is another sub heading
This is some more info
## This is another heading
This is some more info
toc
の IDとテキストにアクセスできるようになったので、これらをループさせてそれぞれを出力し、<NuxtLink>
コンポーネントを使ってリンク先のセクションのIDにリンクさせることができます。
pages/blog/_slug.vue
<nav>
<ul>
<li v-for="link of article.toc" :key="link.id">
<NuxtLink :to="`#${link.id}`">{{ link.text }}</NuxtLink>
</li>
</ul>
</nav>
これでToCリンクが機能し、クリックするとドキュメントの正しい部分に移動します。contentモジュールは自動的に各見出しにidとリンクを追加します。開発ツールでマークダウンファイルの見出しの1つを検査すると、<h2>
タグにidがあるとわかります。これは toc
で見つかったのと同じidで、基本的には toc
が正しい見出しにリンクする方法です。
ダイナミッククラスを使って見出しの深さに基づいて見出しクラスをスタイルすることで、これをさらに改善できます。リンクの深さが2の場合はy軸にパディングを追加し、深さが3の場合は左のマージンと下のパディングを追加します。ここではTailwindCSSクラスを使用していますが、カスタムクラス名やスタイルを自由に使用してください。
pages/blog/_slug.vue
:class="{
'py-2': link.depth === 2,
'ml-2 pb-2': link.depth === 3
}"
ときどき、マークダウンファイルにHTMLを追加したくなることがあります。いくつかのクラスを持つdivを追加して、背景色が青、テキストは白、いくつかのパディングと底辺にマージンを持つようにしてみましょう。
content/articles/my-first-blog-post.md
<div class="bg-blue-500 text-white p-4 mb-4">
This is HTML inside markdown that has a class of note
</div>
また、マークダウンファイル内にVueコンポーネントを追加することもできます。つまり、infoやアラートボックスのようなコンポーネントを再利用する場合、必要なスタイルのコンポーネントを作成し、スロットとしてテキストを渡すことができます。
nuxt.config
ファイルでプロパティ components
を true
に設定することで、アプリケーションにコンポーネントを追加できます。(v2.13以降)
nuxt.config.js
export default {
components: true
}
コンポーネントの自動インポートは、components
フォルダ内にglobal
フォルダを追加してグローバルに登録しない限り、<nuxt-content>
では機能しません。
mkdir components/global
このフォルダ内にInfoBoxコンポーネントを作ってみましょう。
components/global/InfoBox.vue
<template>
<div class="bg-blue-500 text-white p-4 mb-4">
<p><slot name="info-box">default</slot></p>
</div>
</template>
Then in our markdown these components will be available without having to import them. これでmarkdownファイル内で、import文を書く必要もなくコンポーネントを利用できます。
content/articles/my-first-blog-post.md
<info-box>
<template #info-box>
This is a vue component inside markdown using slots
</template>
</info-box>
グローバルコンポーネントはアプリケーション全体で利用できるようになるので、globalフォルダーにコンポーネントを追加する際には注意が必要です。 これは、使用される場合にのみ追加されるcomponentsフォルダーにコンポーネントを追加する場合とは動作が異なります。
YAMLプロパティの他の利点は、propsを通してコンポーネントで利用できるようにすることです。たとえば、著者についてのコンポーネントを持つことができ、ゲストブロガーがいる場合、著者欄を変更できます。 マークダウンファイルの中で、著者の名前、バイオ、画像を含む新しいauthorオブジェクトをフロントマッターに追加できます。
content/articles/my-first-blog-post.md
---
author:
name: Benjamin
bio: All about Benjamin
image: https://images.unsplash.com/.....
---
これでAuthorコンポーネントを作成できるようになりました。
touch components/global/Author.vue
ここでは、著者の画像、著者のタイトル、名前と著者のバイオの動的なdivを作成します。
components/global/Author.vue
<template>
<div>
<img :src="author.img" />
<div>
<h4>Author</h4>
<p>{{ author.name }}</p>
<p>{{ author.bio }}</p>
</div>
</div>
</template>
スタイルはこれらの例から削除されています、スタイルを自分で追加するか、デモコードからスタイルをコピーしてください。
そして、スクリプトタグの中に、オブジェクトであるauthorのpropsを追加し、また、設定を必須に指定できます。
components/global/Author.vue
<script>
export default {
props: {
author: {
type: Object,
required: true
}
}
}
</script>
コンポーネントを使用するには、マークダウンに追加してpropsを渡す必要があります。
content/articles/my-first-blog-post.md
<author :author="author" />
ここにコンポーネントを置くということは、記事ごとにそれを繰り返さなければならないということです。この場合、slugページに直接追加する方が良いでしょう。私たちは著者のpropを article.author
に変更する必要があります。
pages/blog/_slug.vue
<template>
<article>
<h1>{{ article.title }}</h1>
<p>{{ article.description }}</p>
<img :src="article.img" :alt="article.alt" />
<p>Article last updated: {{ formatDate(article.updatedAt) }}</p>
<nuxt-content :document="article" />
<author :author="article.author" />
</article>
</template>
このコンポーネントをglobalフォルダからcomponentsフォルダに直接移動でき、テンプレートで使用しているようにslugページに自動インポートされます。
contentモジュールでは、prismJSを自動的に含めることでコードブロックのスタイルを設定できます。つまり、正しいマークダウン構文を使用してコードブロックを書くことができ、コードブロックは言語に応じてスタイリングされて表示されます。
content/articles/my-first-blog-post.md
```js
export default {
nuxt: "is the best"
}
<p>code styling is easy</p>
}
また、コードブロックの言語の後に角括弧内でファイル名を追加することで、コードブロックのファイル名を追加することもできます。
```markdown
```js[my-first-blog-post.md]
export default {
nuxt: "is the best"
}
ファイル名は、ファイル名クラスを持つspanに変換されます。この例では tailwind クラスを使用していますが、お好みであれば通常の CSS を使用しても構いません。
`assets/css/tailwind.css`
```css
.nuxt-content-highlight {
@apply relative;
}
.nuxt-content-highlight .filename {
@apply absolute right-0 text-gray-600 font-light z-10 mr-2 mt-1 text-sm;
}
prism-themesのように、異なるテーマを使用することができます。それをインストールしてから、nuxt.config
ファイルのcontentオプションにお好みのテーマを追加することができます。
npm install prism-themes
// or
yarn add prism-themes
そして、nuxt.config
ファイルのコンテンツオプションで、prismを使ってマークダウンオブジェクトを追加し、使用したいテーマを追加できます。
nuxt.config.js
content: {
markdown: {
prism: {
theme: 'prism-themes/themes/prism-material-oceanic.css'
}
}
}
これでかなり完成したブログ記事が完成しましたが、ユーザーが簡単に別の記事へ移動できるようになれば素晴らしいことだと思いませんか?まず、記事を複製して3つの記事を作成しましょう。次に、前の記事と次の記事を移動するのための新しいコンポーネントを作成しましょう。
touch components/PrevNext.vue
このコンポーネントでは NuxtLink
コンポーネントの中で v-if
を使用して、以前のブログ記事があるかどうかを確認し、ある場合はその記事へのリンクを追加します。変数prev
とnext
を使って記事のタイトルを出力できます。つまり、次の記事と前の記事を表示するために画像と説明文を含むカードを作成できます。この例ではタイトルだけを表示します。前の記事がない場合は、スタイルを整えるのに便利な空のスパンを表示します。次の記事へのリンクも同じようにします。
components/PrevNext.vue
<template>
<div class="flex justify-between">
<NuxtLink
v-if="prev"
:to="{ name: 'blog-slug', params: { slug: prev.slug } }"
class="text-primary font-bold hover:underline"
>
{{ prev.title }}
</NuxtLink>
<span v-else> </span>
<NuxtLink
v-if="next"
:to="{ name: 'blog-slug', params: { slug: next.slug } }"
class="font-bold hover:underline"
>
{{ next.title }}
</NuxtLink>
<span v-else> </span>
</div>
</template>
このコンポーネントでは、prev
と next
というpropsを渡して、ブログ記事のページでそれらを利用できるようにしています。
components/PrevNext.vue
<script>
export default {
props: {
prev: {
type: Object,
default: () => null
},
next: {
type: Object,
default: () => null
}
}
}
</script>
前の記事と次の記事を asyncData
に追加することで、前の記事と次の記事を取得することができます。前の記事と次の記事を取得するために、prev
と next
という名前の const の配列を作成し、記事フォルダの内容をawaitします。今回はタイトルとslugだけが必要なので、only()
をチェインしてタイトルとスラッグを渡すことができます。
sortBy()
メソッドを使って、データを createdAt 日付の昇順でソートすることができます。次に surround()
メソッドを使用し、パラメータからスラッグを渡します。
そして、記事で行ったのと同じように前の記事と次の記事を返します。
pages/blog/_slug.vue
async asyncData({ $content, params }) {
const article = await $content('articles', params.slug).fetch()
const [prev, next] = await $content('articles')
.only(['title', 'slug'])
.sortBy('createdAt', 'asc')
.surround(params.slug)
.fetch()
return {
article,
prev,
next
}
},
これで、slugページに <prev-next>
コンポーネントを追加できます。
pages/blog/_slug.vue
<template>
<article>
<h1>{{ article.title }}</h1>
<p>{{ article.description }}</p>
<img :src="article.img" :alt="article.alt" />
<p>Article last updated: {{ formatDate(article.updatedAt) }}</p>
<nuxt-content :document="article" />
<author :author="article.author" />
<prev-next :prev="prev" :next="next" />
</article>
</template>
nuxt.config
ファイルで components: true
を設定しているので、このコンポーネントを使用するためにインポートする必要はありません。
データをクエリするとき、ContentモジュールはAPIへのアクセスを提供してくれるので、何が返されているかを直接問い合わせることができます。開発者モードでは、以下のURLでAPIにアクセスできます。http://localhost:3000/_content/。私たちの例では、記事はarticlesと呼ばれるフォルダにあるので、このURLは空になります。
slugの名前を入れれば個別の記事が見れるようになっていますhttp://localhost:3000/_content/articles/my-first-blog-post
JSON Viewer AwesomeのようなChromeの拡張機能を使うと、結果をよりよく見ることができます。
これで、URLで結果を直接クエリし、結果をJSONとして表示できます。これを使用して、すべてのブログ投稿のリストを含むブログインデックスページを作成できます。APIを使用して、利用可能なものを確認できます。私たちとブログのインデックスページでは、title、description、img、slug、authorのみを返します。それがどのようなものか見てみましょう。
http://localhost:3000/_content/articles?only=title&only=description&only=img&only=slug&only=author
ブログインデックスページを作成して、ブログ投稿を一覧表示できるようになりました。すでにインデックスページが作成されているので、このページ内のすべてのデモコードを削除する必要があります。
$content
とparams
をasyncData
関数のコンテキストに渡すと、定数articlesを宣言して、articlesの引数を$content
に渡し、返されるコンテンツをawaitします。 articlesはparamsからのslugです。 APIからテストしたため、 only()
を使用してタイトル、説明、img、slug、authorを取得できます。これにより、必要なものが正確に得られます。 sortBy()
を使用して、createdAtを指定し日付の昇順で並べ替えてから、 fetch()
で記事を返すことができます。
pages/blog/index.vue
<script>
export default {
async asyncData({ $content, params }) {
const articles = await $content('articles', params.slug)
.only(['title', 'description', 'img', 'slug', 'author'])
.sortBy('createdAt', 'asc')
.fetch()
return {
articles
}
}
}
</script>
これで、他のデータプロパティと同じように記事を利用できるようになったため、 v-for
を使用してテンプレートで使用し、すべての記事をループして記事のタイトルと著者名、更新日、説明、そして画像を出力できます。<NuxtLink>
コンポーネントを使用して記事のslugにリンクします。
pages/index.vue
<template>
<div>
<h1>Blog Posts</h1>
<ul>
<li v-for="article of articles" :key="article.slug">
<NuxtLink :to="{ name: 'blog-slug', params: { slug: article.slug } }">
<img :src="article.img" />
<div>
<h2>{{ article.title }}</h2>
<p>by {{ article.author.name }}</p>
<p>{{ article.description }}</p>
</div>
</NuxtLink>
</li>
</ul>
</div>
</template>
contentモジュールでは、whereクエリを使って結果をフィルタリングすることもできます。著者の詳細とその著者によるすべての投稿を表示する著者ページを持つことができます。
touch pages/blog/author/_author.vue
前回と同じように、データを取得するためにasyncDataを使用しますが、今回はwhere()メソッドを追加します。ここでは、paramsで指定した著者名と同じ著者名の投稿を取得したいと思います。
例:
http://localhost:3000/_content/articles?author.name=Maria
作成者にオブジェクトを使用しているので、nuxt.configファイルのcontentプロパティにオプションとしてnestedPropertiesを追加して、クエリを実行したいものを渡します(ドット表記のクエリの場合のみ)。
nuxt.config.js
export default {
content: {
nestedProperties: [
'author.name'
]
}
}
ご覧のように、私たちはすべてのデータを取得していますが、著者であるMariaのデータのみを取得しています。もし大文字を使わずにmariaを使っていたら、何も返ってきません。そこで、$regex
を使って大文字のままにすることができます。
そして、このページに表示したいすべての詳細を取得します。先ほどの例では only()
メソッドを使って必要なものを返しましたが、かなり多くのコンテンツを必要とするので、代わりに without()
メソッドを使って、返したくないもの、つまり投稿の本文を渡すことができます。
pages/blog/author/_author.vue
<script>
export default {
async asyncData({ $content, params }) {
const articles = await $content('articles', params.slug)
.where({
'author.name': {
$regex: [params.author, 'i']
}
})
.without('body')
.sortBy('createdAt', 'asc')
.fetch()
return {
articles
}
}
}
</script>
配列を使って without()
メソッドにbody
以外のものを渡すことができます。
without(['body', 'title'])
その後、これらのデータを使用して、著者名とバイオだけでなく、各投稿を示す素敵な著者ページを作成できます。
pages/blog/author/_author.vue
<template>
<div>
<h1>Author: {{ articles[0].author.name }}</h1>
<p>Bio: {{ articles[0].author.bio }}</p>
<h3>Here are a list of articles by {{ articles[0].author.name }}:</h3>
<ul>
<li v-for="article in articles" :key="article.slug">
<NuxtLink :to="{ name: 'blog-slug', params: { slug: article.slug } }">
<img :src="article.img" :alt="article.alt" />
<div>
<h2>{{ article.title }}</h2>
<p>{{ article.description }}</p>
<p>{{ formatDate(article.updatedAt) }}</p>
</div>
</NuxtLink>
</li>
</ul>
</div>
</template>
この例ではすべてのスタイルが削除されていることに注意してください。あなた自身でページのスタイルを設定するか、デモコードからスタイルをコピーできます。
日付をフォーマットするために、先ほど作成したメソッドを追加できます。
pages/blog/author/_author.vue
methods: {
formatDate(date) {
const options = { year: 'numeric', month: 'long', day: 'numeric' }
return new Date(date).toLocaleDateString('en', options)
}
}
そして、もちろんブログ記事から新しい著者ページへのリンクもしておきましょう。
components/Author.vue
<NuxtLink :to="`/blog/author/${author.name}`">
<img :src="author.img" />
<div>
<h4>Author</h4>
<p>{{ author.name }}</p>
<p>{{ author.bio }}</p>
</div>
</NuxtLink>
Nuxt/contentモジュールでは、search()
メソッドを使って記事を検索できます。
まず、検索コンポーネントを作成してみましょう。
touch components/AppSearchInput.vue
次に、空の文字列として始まるsearchQueryを返すdataプロパティと、空のArticles配列を追加します。 次に、Vueのwatchメソッドを使用して、searchQueryの引数を渡すsearchQuery関数を監視します。 searchQueryがない場合、articles配列は空であり、returnを呼び出すだけです。 そうでない場合は、記事を取得して、 $ content
が記事を渡すのを待ちます。 これで、 limit()
メソッドを使用して返される結果の数を制限できます。次に、 search()
メソッドを使用してsearchQueryを引数として渡し、 fetch()
メソッドを最後までチェーンします 。
components/AppSearchInput.vue
<script>
export default {
data() {
return {
searchQuery: '',
articles: []
}
},
watch: {
async searchQuery(searchQuery) {
if (!searchQuery) {
this.articles = []
return
}
this.articles = await this.$content('articles')
.limit(6)
.search(searchQuery)
.fetch()
}
}
}
</script>
次に、テンプレートに入力を追加し、v-model
を使ってそれをSearchQueryのデータプロパティに接続する必要があります。次に、記事がある場合は v-for
を使って記事をリストアップし、<NuxtLink>
コンポーネントを使って記事にリンクします。
components/AppSearchInput.vue
<template>
<div>
<input
v-model="searchQuery"
type="search"
autocomplete="off"
placeholder="Search Articles"
/>
<ul v-if="articles.length">
<li v-for="article of articles" :key="article.slug">
<NuxtLink :to="{ name: 'blog-slug', params: { slug: article.slug } }">
{{ article.title }}
</NuxtLink>
</li>
</ul>
</div>
</template>
これで、コンポーネントをページの任意の場所に追加して使用できるようになりました。
pages/_slug.vue
<AppSearchInput />
このページの改善されたスタイリングについては、デモコードを参照してください。また、検索コンポーネントを含む追加されたヘッダーコンポーネントと同様に、著者とインデックスページに表示されます。
私たちのブログは本当に素晴らしく、ページ上のコンテンツを修正する必要がある場合は、ライブエディット機能によってブラウザ上で直接修正できます。あなたがしなければならないことは、開発モードでページをダブルクリックするだけです。すぐにライブエディット画面が開きます。ここでは、あなたのテキストとフロントマターのいずれかを変更できます。グローバルコンポーネントフォルダーにあるコンポーネントを追加できます。クリックするだけでブラウザ上で変更をライブで見ることができ、エディターやコンソールでファイルが変更されて保存されたことを確認できます。
新しいブログをデプロイしたい場合は、nuxt build
と nuxt export
コマンドを実行します。nuxt build
コマンドはアプリをビルドし、すべてのwebpackアセットを追加して.js
バンドルを作成します。次にnuxt export
コマンドを実行すると、html、css、js、画像を静的アセットとしてエクスポートします。クローラーがすべてのリンクをクロールして動的なルートを生成してくれるので、ルートプロパティを追加したり、新しいページを取得するために何かをする必要がないことに気づくでしょう。
次に nuxt serve
コマンドを使うことで、デプロイ前にブラウザで確認できるように、本番用の静的サイトを提供できます。
コンテンツをビルドから分離することで、新しいマークダウンページを追加できます。nuxt build
を実行する必要があるのは、.vueページやコンポーネント、またはコンテンツフォルダーにないものを変更する場合だけです。(コンテンツを変更するたびにnuxt build
する必要はない)
contentを使った作業はとても楽しく、あなたができることはたくさんあります。あなたの作品をDiscordチャンネルのshowcaseで紹介することを忘れないでください。まだ登録していませんか?これからもNuxt.jsの新しいコンテンツや機能をどんどんリリースしていきますので、今がチャンスです! sign upお楽しみに。