Vue.jsでMarkdownをパースするためのvue-markdownの紹介と絵文字サジェストを作った話

  • 17
    いいね
  • 0
    コメント

はじめに

Vue.jsでMarkdownエディタを作ろうと思って探していたところ、vue-markdownという便利なコンポーネントがあったのでそれの紹介と、それ使う際絵文字のサジェストがあったらうれしいなと思い作った話です。

vue-markdown

vue-markdownはmarkdown-itというMarkdownパーサをラップして、Vue.jsで使いやすいようにコンポーネントにした簡単なライブラリです。ソースの中身を眺めてみるとmarkdown-itをコンポーネントにしているだけで、余計なことをほとんどしていないことがわかります。

vue-markdown

markdown-it

使い方も簡単で以下のようにpropsのsourceにMarkdownで書いた文字列を入れるだけで簡単にMarkdownエディターが作れます。

<div id="app">
  <h1>Vue Markdown Editor</h1>
  <div class="editor-main">
    <div class="main">
      <textarea class="editor" v-model="source"></textarea>
      <div class="preview">
        <vue-markdown :source="source"></vue-markdown>
      </div>
    </div>
  </div>
</div>
import VueMarkdown from 'vue-markdown'
export default {
  name: 'app',
  data () {
    return {
      source: ""
    }
  },
  components: {
    VueMarkdown
  }
}

vue-mark-down.gif

絵文字サジェストを作った話

これだけだと作っただけの工夫のないエディタになってしまうので、何か味付けをと思い考えたのですが。絵文字がサジェストされると便利で良いんじゃないかと思い絵文字サジェストの機能を作ってみました。

サジェストの機能を作るのはかなり大変で、今回はちょっと日和って一番最後に入力している単語を対象にしています。

絵文字入力の前はスペースが空くのでスペースで単語を区切って一番最後の入力している単語が : であればサジェストを表示するという簡単なロジックです。

<div>
    <span>{{ preConvertEmoji }}</span>
    <ul>
      <li v-for="key in suggest_filter()">
        {{ key }} : {{ emojiList[key] }}
      </li>
    </ul>
    <textarea class="editor" v-on:keyup="enter"></textarea>
</div>
//絵文字の一覧jsonを読み込む。
//絵文字一覧のJSONはmarkdown-it-emojiから拝借
//https://github.com/markdown-it/markdown-it-emoji
import emojiOrigin from '../data/light.json'

export default {
  name: 'suggest',
  data () {
    return {
      emojiList: emojiOrigin,
      preConvertEmoji: ""
    }
  },
  methods: {
    suggest_filter: function () {
      const emoji = this.preConvertEmoji.replace(/:/g, '')

      if (emoji == ""){
        return []
      }

      //読み込んだemojiOriginから前方一致で候補を5つ出す
      return Object.keys(emojiOrigin).filter(function (key) {
        return key.indexOf(emoji) == 0
      }).slice(0, 5)
    },
    enter: function(data){
      const words = data.target.value.split(/\s/)
      const lastWord = words.pop()
      //最後に入力している単語がコロンからはじまっていれば絵文字入力と見なして入力中の文字を保持する
      if(lastWord.indexOf(':') == 0){
        this.preConvertEmoji = lastWord
      } else {
        this.preConvertEmoji = ""
      }
      // 親コンポーネントに入力を渡すために$emitを使っている
      this.$emit('enter', data.target.value)
    }
  }
}

動きとしてはこんな感じになります。

vue-mark-down_2.gif

ソースコードは以下にあります。
https://github.com/nasum/vue-markdown-editor

サジェストを出すだけでこの中から選択とかは出来ませんが、入力の助けにはなると思います。今後うまく改修してこの中から選択して入力することや、入力しているカーソルの部分への表示、最後の単語だけでなくどの位置でもサジェストが出るようにしたいところです。

まとめ

Vue.jsでMarkdownエディタを作るのに便利なvue-markdownの紹介をしました。絵文字サジェストはちょっとショボかったものの、自分が欲しいものに少し近づけたのでこれから発展させていきたいところです。

明日(12/05)の担当は@akifoさんです。

この投稿は Vue.js Advent Calendar 20164日目の記事です。