ゴール
- マークダウン記入をするとすぐにプレビューされる
- マークダウンから変換されてできた
内はシンタックスハイライトされてる
- これらをvue上で行う
使用した js
marked
- マークダウン入力をhtmlに変換する
prism
<code></code>
内をシンタックスハイライトする
lodash
- 上記処理の発生を間引くためのdebounce処理に。
スクリプト
debounce
- 書いたらすぐプレビューと言っても、文字打つ度にプレビュー処理+ハイライト処理するのも非効率なので、入力中に処理は行わず、入力後一定時間入力がなかったら処理を走らせる。
- そのために
v-model
は使わず@input
で debounce のメソッドを走らせた。 - debounce には lodash を使った。でもこのくらいならsetTimeoutで自分でやってもいい。
methods: {
update: lodash.debounce(function (e) {
this.body = e.target.value
}, 500),
}
marked.setOptions
- ここに ハイライト処理を入れることができる
- ただ入れるだけじゃなく、すこしおもてなしが必要
created: function(){
marked.setOptions({
breaks: true,
langPrefix: 'language-',
highlight: function (code, lang) {
if ( lang && lang.match(":")) { // : 付きの lang から言語名だけ切り出す
lang = lang.substring(0,lang.indexOf(":"));
}
if(lang in Prism.languages){ // 対応言語(自分で指定できる)内にlangの言語があれば
return Prism.highlight(code, Prism.languages[lang]);
}else{ // なにもない場合はそのままのcode
return code
}
}
})
全体
markdown.vue
<template>
<form>
<textarea placeholder="# 本文" rows=24
@input="update"></textarea>
<div v-html="compiledMarkdown"></div>
</section>
</form>
</template>
<script>
import marked from 'marked'
import Prism from 'prismjs'
import lodash from 'lodash'
export default{
data: function(){
return{
title: '',
body: '',
}
},
computed: {
compiledMarkdown: function () {
return marked(this.body, { sanitize: true })
}
},
created: function(){
marked.setOptions({
breaks: true,
langPrefix: 'language-',
highlight: function (code, lang) {
if ( lang && lang.match(":")) {
lang = lang.substring(0,lang.indexOf(":"));
}
if(lang in Prism.languages){
return Prism.highlight(code, Prism.languages[lang]);
}else{
return code
}
}
})
},
methods: {
update: lodash.debounce(function (e) {
this.body = e.target.value
}, 500),
}
}
</script>