はじめに
NuxtでQiitaのようなマークダウンエディター+プレビュー機能のブログを作ろうとした時に、
markdown-it-vueという便利なライブラリがあったので遊んでみました。
最終的にはこんな感じのシンタックスハイライト+プレビュー機能のついたマークダウンエディターを作ります。
コード挿入の黒い背景色やh1タグなどは個人的な好みで後から色を変えています。
このライブラリを導入するだけででマークダウンとシンタックスハイライト、警告ボックスなど簡単に実装できるので、個人開発では試してみるのもアリです。
ただ少しマイナーなライブラリのため、不安な方はmarked.js
とHighlight.js
を組み合わせる方式をとったほうがいいと思います。
markdown-it-vue
対応言語はこちらで確認できます。有名な言語には大抵対応しているので困ることはないです。
他にもサポートとして円グラフやシーケンス図が対応しています。
詳しくはREADMEをご覧ください。
実装
まずはnuxtで適当なプロジェクトを作りましょう。
初期設定などは割愛します。
ターミナル
$ create-nuxt-app markdown-app
```
`markdown-it-vue`をインストールします。
````shell:ターミナル
$ cd markdown-app
$ yarn add markdown-it-vue #yarnの場合
$ npm install markdown-it-vue #npmの場合
```
`pages/index.vue`をまるっと以下のように書き換えます。
まずは公式の[README](https://github.com/ravenq/markdown-it-vue#usage)に書かれてる簡単なサンプルで動作確認しましょう。
```vue:pages/index.vue
<template>
<div>
<markdown-it-vue class="md-body" :content="content" />
</div>
</template>
<script>
import MarkdownItVue from 'markdown-it-vue'
import 'markdown-it-vue/dist/markdown-it-vue.css'
export default {
components: {
MarkdownItVue
},
data() {
return {
content: '# your markdown content'
}
}
}
</script>
```
```shell:ターミナル
yarn dev #yarnの場合
npm run dev #npmの場合
```
`http://localhost:3000`にアクセスすると、以下のようにマークダウンが反映されています。
若干見づらいですが、ボーダーもついていますね。
公式のスタイル一覧は[こちら](https://github.com/ravenq/markdown-it-vue#screenshot)
![スクリーンショット 2021-05-11 23.53.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631045/c419c0bd-c0da-51a7-e25e-bd1d287f4059.png)
## プレビュー機能を作る
簡単なサンプルを載せます。
細かいスタイルは各自で修正してください。
```vue:pages/index.vue
<template>
<div class="wrap">
<div class="editer">
<textarea
class="md-editer"
v-model="content"
placeholder="マークダウンで書く"
></textarea>
</div>
<div class="preview">
<markdown-it-vue class="md-body" :content="content" />
</div>
</div>
</template>
<script>
import MarkdownItVue from "markdown-it-vue";
import "markdown-it-vue/dist/markdown-it-vue.css";
export default {
components: {
MarkdownItVue
},
data() {
return {
content: ""
};
}
};
</script>
<style lang="scss" scoped>
.wrap {
width: 100%;
height: 800px;
display: flex;
padding-top: 40px;
.editer {
width: 50%;
.md-editer {
width: 100%;
height: 100%;
border: solid 1px rgb(206, 205, 205);
font-size: 1.1rem;
}
}
.preview {
width: 50%;
height: 100%;
border: solid 1px rgb(206, 205, 205);
padding: 10px;
}
}
</style>
```
**プレビュー機能は`textarea`と`content`を`v-model`で紐付けることが肝です。**
以下の画像の通り、半分より左がエディター、右がプレビューです。
実際にマークダウンで書くと即座に反映されると思います。
![スクリーンショット 2021-05-12 0.48.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631045/de0d6a09-dbb8-514b-bff8-863715ab2a50.png)
実際に[公式の書き方](https://github.com/ravenq/markdown-it-vue#screenshot)を参考に書いてみるとこんな感じ。
![スクリーンショット 2021-05-12 1.13.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631045/2ffbf113-8ac5-59c7-da73-31d2b5e456d0.png)
これが`markdown-it-vue`のデフォルトスタイルです。
これだけでも十分ですが、私はコード挿入の背景色をQiitaのように黒っぽくしたいと思ったので、独自のCSSを作ることにしました。
もし独自のCSSにしたいと思った方はこの先もお読みください。
## 独自のCSSを作る
`assets/markdown.scss`を作成して以下をコピペ。
```scss:assets/markdown.scss
$mainColor: #36cbfa;
.md-body {
.markdown-body {
h1,
h2 {
border-bottom: none;
border-left: solid 10px $mainColor;
padding: 5px;
}
h2 {
border: none;
color: $mainColor;
}
pre {
background-color: #334146;
code {
color: rgb(236, 236, 236);
font-family: inherit;
line-height: 1.8;
font-size: 0.9rem;
.hljs-keyword {
color: rgb(201, 146, 253);
}
.hljs-title {
color: $mainColor;
}
.hljs-attr {
color: rgb(247, 210, 0);
}
.hljs-attribute {
color: palegreen;
}
.hljs-variable {
color: orange;
}
.hljs-selector-class {
color: rgb(214, 157, 50);
}
.hljs-built_in {
color: #d19719;
}
.hljs-symbol {
color: rgb(18, 167, 253);
}
.hljs-number {
color: rgb(172, 255, 172);
}
.hljs-string {
color: rgb(190, 228, 190);
}
.hljs-subst {
color: rgb(250, 99, 89);
}
.hljs-meta {
color: #6594fa;
}
}
}
}
}
```
```js:nuxt.config.js
css: ["@/assets/markdown.scss"]//追記
```
こんな感じで独自のスタイルが反映されたら成功です!
![スクリーンショット 2021-05-12 10.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631045/d7573061-9edb-60de-a0fc-325bbec92ef7.png)
# 最後に
`markdown-it-vue`を使えば簡単にマークダウンとシンタックスハイライトが実装できました。
プレビュー機能も実装するとマークダウンの反映が確認できて便利ですね。
皆さんも独自のCSSを割り当てて遊んでみてください。
## 参考
* [markdown-it-vue](https://github.com/ravenq/markdown-it-vue)