Nuxt ContentでコンポーネントにクラスやIDを付ける
Nuxt Contentでスタイリングする際、<style scoped>p {margin-bottom:1rem;}</style>のように、直接要素にCSSを当てるのが簡単ですが、クラスやIDなど各種属性を付けることもできます。Tailwind CSSなどのUIライブラリを使う場合に便利な方法です。
専用のコンポーネントを作成
Nuxt Contentでは/components/content/フォルダ内にコンポーネントを作成すると、専用のカスタムコンポーネントとして使うことができます。今回のクラスやIDの付与はこのシステムを利用したものです。
例として、<p>タグにmb-4のクラスを付ける場合は、/components/content/Paragraph.vueのファイルを作成し、以下のコードを記述します。
<template>
<p class="mb-4">
<slot></slot> <!-- 文字がここに展開される -->
</p>
</template>
<h2>タグや<ul>タグなど、他にも属性を付けたいコンポーネントがあれば、同じ要領で進めていきます。
作成したコンポーネントを使う
作成したコンポーネントは「全体に反映させる」か「レンダーコンポーネントごとに反映させる」か2通りの方法があり、両者を併用することもできます。
全体に反映させる
nuxt.config.tsファイルのcontent設定に記述します。Nuxt Content関連のコンポーネント全体に反映されます。
以下は先ほど作成したParagraph.vueファイルを読み込む設定です。
export default defineNuxtConfig({
content: {
markdown: {
tags: {
p: "Paragraph",
},
},
},
});
レンダーコンポーネントごとに反映させる
ページごとにカスタマイズしたい場合などは、レンダーする側で使うコンポーネントを直接指定することもできます。
Markdownの内容をレンダーするために<ContentRenderer>コンポーネントまたは<ContentRendererMarkdown>コンポーネントを使うのですが、そのPropsのcomponentsにオブジェクトの形式で指定します。
例として、/pages/about.vueファイルで、/content/about.mdファイルを読み込み、先ほど作成した/components/content/Paragraph.vueを<p>タグとして使う場合は以下のようになります。
<template>
<div>
<ContentDoc v-slot="{ doc }" path="/about">
<h1>{{ doc.title }}</h1>
<ContentRenderer :value="doc" :components="{ p: 'Paragraph' }" />
</ContentDoc>
</div>
</template>
ファイル名を適宜変更することで、同じタグでも見た目を変えることができます。
もっと良いやり方がある気がする
当初、今回のやり方を知らず、以下のように指定していたのですが、タグがそのまま展開されてしまい上手くいきませんでした。
<ContentRenderer :value="content" :components="{ p: 'p.mb-4' }" />
タグにクラスをつける程度のことであれば、こちらの方が便利な気がします。
もしくは、以下のようにオブジェクトをさらに深くして、各属性を指定する仕様も馴染みのある形で良い気がします。
<ContentRenderer :value="content" :components="{ p: { class: 'mb-4' } }" />