Vue.js + Marked + highlight.jsでマークダウンエディタを実装する

Vue.jsでマークダウンエディタを作ったので方法を備忘録としてまとめます。

最後まで読めば、誰でも手軽に上記画像のマークダウンエディタが作れるようになります。

記事の信頼性
  • 独学で未経験から従業員300名以上の自社開発企業へ転職しました。
  • 実務ではVue.jsとRailsを毎日書いています。
目次

Vue.jsでマークダウンエディタを実装する方法

Vue.jsでマークダウンエディタを実装するために必要なのは次の3ステップです。

  1. ライブラリのインストール
  2. マークダウンをHTMLに変換する関数の作成
  3. 入力値をHTMLに変換して表示する

順番に解説します。

1. ライブラリのインストール

まずはライブラリをインストールします。

この記事では以下のライブラリを使います。()内はバージョンです。

使うライブラリ
  • marked(11.1.1):
    マークダウン文字列をHTMLに変換するためのライブラリ
  • highlight.js(11.9.0):
    マークダウンのコード部分をシンタックスハイライトするためのライブラリ
  • marked-highlight(2.1.0):
    上記2つを組み合わせて使うためのヘルパーライブラリ

↓のコマンドを実行してインストールしましょう。

npm install marked marked-highlight highlight.js

2. マークダウンをHTMLへ変換する関数の作成

インストールしたライブラリを用いてマークダウンをHTMLへ変換する関数を作成します。

<script setup lang="ts">
import { Marked } from 'marked'
import hljs from 'highlight.js'
import { markedHighlight } from 'marked-highlight'
// highlight.js ライブラリで提供されるスタイルシートのインポート
import 'highlight.js/styles/github-dark.css'

const convertMarkdownToHtml = async (markdown: string) => {
  const marked = new Marked(
    markedHighlight({
      langPrefix: 'hljs language-',
      highlight(code, lang) {
        const language = hljs.getLanguage(lang) ? lang : 'plaintext'
        return hljs.highlight(code, { language }).value
      }
    })
  )
  return await marked.parse(markdown)
}
</script>

インポートしているスタイルシートに関して、今回はgithub-dark.cssを選択していますが、他にもたくさんあるのでこちらから選んでみてください。

3. 入力値をHTMLに変換して表示する

最後に入力値をHTMLに変換して表示する部分を実装します。

画面左にマークダウン形式で記述すると画面右にHTML形式で表示される機能を作ります(Qiitaの記事執筆画面のイメージ)

<script setup lang="ts">
import { Marked } from 'marked'
import hljs from 'highlight.js'
import { markedHighlight } from 'marked-highlight'
import 'highlight.js/styles/github-dark.css'
import { ref } from 'vue';
import { watch } from 'vue';

const convertMarkdownToHtml = async (markdown: string) => {
  const marked = new Marked(
    markedHighlight({
      langPrefix: 'hljs language-',
      highlight(code, lang) {
        const language = hljs.getLanguage(lang) ? lang : 'plaintext'
        return hljs.highlight(code, { language }).value
      }
    })
  )
  return await marked.parse(markdown)
}

const inputMd = ref('')

const inputHtml = ref('')

// 入力値の変更を監視
watch(inputMd, async (newInput) => {
  inputHtml.value = await convertMarkdownToHtml(newInput);
});

</script>

<template>
  <v-container>
    <v-row>
      <v-col>
        <v-textarea v-model="inputMd" variant="outlined" rows="15"></v-textarea>
      </v-col>
      <v-divider vertical></v-divider>
      <v-col>
        <div v-html="inputHtml"></div>
      </v-col>
    </v-row>
  </v-container>
</template>

watchプロパティを使い、入力値が変更されるたびにconvertMarkdownToHtml関数による変換を実行しています。

上記のように実装した画面が↓です。

※UIフレームワークとしてVuetifyを使っていますが、レイアウトは今回の本質ではないので気にしなくてOKです。

無事にマークダウンエディタが実装できました。

まとめ

実装自体は意外とカンタンにできましたが、コードブロック内のスタイル変更のやり方が分からず苦労しました。

今回はgithub-dark.cssを選びましたが、こちらからお好みのシンタックスハイライトをお選びください。

参考になれば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

未経験でSESから従業員300名以上の自社開発企業に転職しました。業務や個人開発で直面した問題や、転職・学習の経験を発信していきます。

コメント

コメントする

目次