プログラミング学習

vueでmdの読み込み5選(nuxt/contentの使い方)

プログラミング学習

nuxtでmdの読み込もうとしたら、いろいろでてきたため、めもしておきます。最終的に@nuxt/contentを採用しました。

nuxtでmdの読み込み比較

ぐぐったらいろいろとでてきました。

  • rontmatter-markdown-loader
  • raw-loader
  • markdown-it
  • markdown-to-vue-loader
  • nuxt/content

軽く口コミを調査しました。

frontmatter-markdown-loader

raw-loader

npmをみると、ダウンロード数は多そうです。

markdown-it

nuxt/content

raw-loaderの記事をQiitaに書いていたきらぷかさん、のちほどnuxt/contentをおしています。

悪評もなかったし、Nuxtに備わった機能なのでNuxt/Contentにしました。

目次や全文検索など気になる機能もあったのも後押ししました。

開発モードでのビックリするほど高速なホットリロード

Markdownの中でVueコンポーネントを利用できます

全文検索

静的サイト生成(SSG)のサポートnuxt generate

強力なクエリビルダーAPI (MongoDBライク)

PrismJSを利用した、Markdown内コードブロックのシンタックスハイライト

目次の自動生成

Markdown, CSV, YAML, JSON(5)

XMLを適切に処理します

hooksによる拡張

https://content.nuxtjs.org/ja/
スポンサーリンク

npm install @nuxt/content

インストール。

npm install @nuxt/content

nuxt.configを設定。ここまでは公式のまんま。

{
  modules: [
    '@nuxt/content'
  ],
  content: {
    // Options
  }
}
スポンサーリンク

nuxt/contentの使い方(ブログも作れる)

単純にmdの読み込み

今回はヘルプページ を作成します。まずテスト読み込み。

contentのフォルダが生成されているため、とりあえず、フォルダ直下にtext.mdを作成します。

---
title: タイトル
---

# テスト

テストです。

次はvue側。表示はこう。await $content(‘test’).fetch()で取得しています。

async asyncData({ $content }) {
  const helps = await $content('test').fetch()

  return {
    helps
  }
}
<article>
  <h1>{{ helps.title }}</h1>
  <nuxt-content :document="helps" />
</article>

v-forで一覧取得

しかし、今回はヘルプページ の作成のためv-forで一覧取得にしたいです。

フォルダを掘ってmdファイルを配置します。testをhelpsというフォルダ名に変更します。

  async asyncData({ $content }) {
    const helps = await $content('helps')
      .sortBy('slug')
      .fetch()
    return { helps }
  }

並び順がおかしかったため、sortByを追加しました。

sortByもいろいろあります。

.sortBy('title') // mdのタイトル
.sortBy('slug')  // ファイル名

slugの場合、01.mdみたいな感じにするとうまく並びます。

html側もv-forで回して一覧表示に変えます。

<div v-for="help in helps" :key="help.slug">
  <nuxt-link :to="'/helps/' + help.slug">
    {{ help.title }}
  </nuxt-link>
</div>

slug.vueを追加

slugにあたるところがありません。_slug.vueを作成します。この際__tmp.vueみたいなゴミファイルがあると正常に動作しないことがあるため注意しましょう。

params.slugはnuxtのリファレンスを参照しましょう。

ページディレクトリ

htmlです。helps.titleはタイトルを表示しなければなくてもかまいません。

<template>
  <article>
    <h1>{{ helps.title }}</h1>
    <nuxt-content :document="helps" />
  </article>
</template>

javascriptです。

export default {
  async asyncData({ $content, params }) {
    const helps = await $content('helps/', params.slug).fetch()
    return { helps }
  }
}

フォルダ構造

├── content
│   └── helps
│       ├── qa1.md
│       ├── qa2.md
│       └── qa3.md
~
├── pages
│   ├── helps
│   │   ├── _slug.vue
│   │   └── qa-list.vue
│   └── index.

最初リンク切れをおこしました。contentとpagesの直下にあるhelpsというフォルダ名が同名じゃないとダメでした。

また、こちらはすぐ想像がつくかもしれませんが、test,vueとtest.mdという感じで同じファイルがあるのもダメです。

ヘルプファイルをカテゴリ分けする

カテゴリごとにファイルを管理したい場合もあるでしょう。

VsCode上で階層を移動させます。qa-list.vueのhtml側はリンクを修正します。urlが変わります。

<div v-for="help in helps" :key="help.slug">
  <nuxt-link :to="'/helps/category-a/' + help.slug">
    {{ help.title }}
  </nuxt-link>
</div>

JavaScriptも修正します。ここを変えると表示されるコンテンツ名が変わります。

  async asyncData({ $content }) {
    const helps = await $content('helps/category-a')
      .sortBy('title')
      .fetch()
    return { helps }
  }

_slug.vueも読み込みを修正します。ここを変えると読み込まれるコンテンツの中身が変わります。

export default {
  async asyncData({ $content, params }) {
    const helps = await $content('helps/category-a', params.slug).fetch()
    return { helps }
  }
}

htmlの埋め込み

mdファイルに普通に書けばOKでした。

<p><a href="https://www.google.com/">google</a></p>

まあ、リンクはmarkdownで書けますけどね。

スポンサーリンク

nuxt/contentのcssの読み込み

.nuxt-contentをつければ、そこのみに指定できるようです。場所は_slug.vueとかがわかりやすいかもです。

<style>
.nuxt-content h1 {
  font-size: 50px;
  color: green;
}
</style>

行間を変えたい場合はこうです。

.nuxt-content p {
  line-height: 180%;
}

default.vueに書いてあるcssなども普通に使えます。

ただ、ヘルプの場合、_slug.vue側でレイアウトを作る方が早い気がします。

<template>
  <article>
    <b-container fluid="xl">
      <b-row class="mx-5 my-0 py-0">
        <b-col cols="12">
          <div class="qa-q">
            <h2 class="help-title">{{ helps.title }}</h2>
          </div>
          <div class="qa-a">
            <nuxt-content :document="helps" />
          </div>
        </b-col>
      </b-row>
    </b-container>
  </article>
</template>

大枠のレイアウトはvue側で作成し、見出しやコンテンツ内の要素は_slug.vueもしくはdefault.vueですかね。

ご参考になれば幸いです。

コメント

タイトルとURLをコピーしました