最近は個人的にnuxt3をよく触っています。練習としてちょっとしたアプリを作っているのですが、何らかの文書をマークダウンで扱えると文書構造を表現できて便利です。そこで、今回はnuxt3でマークダウンエディタを扱ってみます。
nuxt3(vue3)でも使えるマークダウンエディタを探したところ、EasyMarkDown Editorというライブラリがシンプルで軽量そうでしたので、そちらを使って実装してみます。
ライブラリ | GitHub Star | GitHub Link | npm UnpackdSize |
easy-markdown-editor | 1.8k | https://github.com/Ionaru/easy-markdown-editor | 495kB |
(2022/12/18 調査時点)
環境
- Node.js v16.18.1
- Nuxt3 stable
- EasyMDE 2.18.0
インストール
nuxtをセットアップして、easymdeをインストールすれば準備完了です。
1 2 3 4 |
$ npx nuxi init md-sample $ cd md-sample/ $ npm i $ npm i easymde |
cssの適用
EasyMDEのデザインを適用するためにnuxt.config.tsにcssを定義します。
1 2 3 4 |
// https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ css: ["easymde/dist/easymde.min.css"], }); |
EasyMDEを組み込む
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<script lang="ts" setup> import type EasyMDE from "easymde"; let mde: InstanceType<typeof EasyMDE> | null = null; const content = ref(""); const contentArea = ref(); onMounted(async () => { const EasyMDE = (await import("easymde")).default; mde = new EasyMDE({ element: contentArea.value!.$el, }); mde.codemirror.on("change", () => { if (mde) { content.value = mde.value(); } }); }); </script> <template> <div> <textarea ref="contentArea" v-model="content" rows="5" placeholder="markdown形式で説明を記述できます。" maxlength="300" /> </div> </template> |
EasyMDEですが、そのままSSRで動かすと以下のようなエラーとなってしまいました。内部でnavigatorが参照されているのですが、SSRではそんなプロパティはないよと怒られます。
1 |
navigator is not defined |
そのため、上記例ではmounted
フックの中で動的インポートを使ってEasyMDEをクライアントサイドで読み込ませるように対処しました。
EasyMDEでは、初期化時の引数でelementプロパティにDOM要素を渡す必要があるため、refでcontentAreaを設定しています。
適用すると以下のようなカッコイイエディタが表示されます。
参考リンク
- https://www.npmjs.com/package/easymde
- https://github.com/Ionaru/easy-markdown-editor
- https://codemirror.net/
コメント