前回は以下の記事でNuxt3にマークダウンエディタのeasymdeを導入してみました。

Nuxt3でマークダウンエディタを使う
最近は個人的にnuxt3をよく触っています。練習としてちょっとしたアプリを作っているのですが、何らかの文書をマークダウンで扱えると文書構造を表現できて便利です。そこで、今回はnuxt3でマークダウンエディタを扱ってみます。nuxt3(vue...
マークダウンで文字入力できるようになったら絵文字も入力したくなります。今回はマークダウンエディタに絵文字ピッカーを組み込んでみます。
環境
- Node.js v16.18.1
- Nuxt 3.2.3
- EasyMDE 2.18.0
- vue3-emoji-picker 1.1.7
インストール
vue3-emoji-pickerをインストールします。
$ npx nuxi init md-sample $ cd md-sample/ $ yarn $ yarn add easymde vue3-emoji-picker
絵文字ピッカーを追加したイメージ
easymdeではツールバーに任意のボタンを追加することができます。ツールバーに顔文字のボタンがあるとわかりやすそうです。最終的な形は以下のようになります。顔文字アイコンを押すと絵文字ピッカーを表示するようにしてみます。

codemirrorの導入
前回の記事のとおりeasymdeを導入します。
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
css: ["easymde/dist/easymde.min.css"],
});
<script lang="ts" setup>
import 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) return;
content.value = mde.value();
});
});
</script>
<template>
<div>
<textarea
ref="contentArea"
v-model="content"
rows="5"
placeholder="markdown形式で説明を記述できます。"
maxlength="300"
/>
</div>
</template>
これで以下のようなビューが表示されます。適当に文字を入力しています。スタイルも適用されてそうです。

絵文字ピッカーの追加
続いてツールバーの一番右に顔文字アイコンを追加し、アイコンをクリックしたら絵文字ピッカーが画面右下に表示されるようにしてみます。
コンポーネント内で絵文字ピッカーコンポーネントを使えるようにプラグインを追加します。
import EmojiPicker from "vue3-emoji-picker";
import "vue3-emoji-picker/css";
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component("EmojiPicker", EmojiPicker);
});
vue3-emoji-pickerの型宣言が見つからないエラーが出るため、以下のようにアンビエント宣言を追加します。
declare module "vue3-emoji-picker";
最終的なコードは以下のようになります。
<script lang="ts" setup>
import EasyMDE from "easymde";
let mde: InstanceType<typeof EasyMDE> | null = null;
const content = ref("");
const contentArea = ref();
const displayEmojiPicker = ref(false);
onMounted(async () => {
const EasyMDE = (await import("easymde")).default;
mde = new EasyMDE({
toolbar: [
"bold",
"italic",
"heading",
"|",
"quote",
"|",
"preview",
"side-by-side",
"fullscreen",
{
name: "Emoji",
title: "Emoji",
className: "fa fa-smile-o",
action: (mde: EasyMDE) => {
displayEmojiPicker.value = !displayEmojiPicker.value;
},
},
],
element: contentArea.value!.$el,
});
mde.codemirror.on("change", () => {
if (!mde) return;
content.value = mde.value();
});
});
function onSelectEmoji(emoji: any) {
if (!mde) {
return;
}
// カーソル位置に絵文字追加
// See https://codemirror.net/5/doc/manual.html
const { line, ch } = mde.codemirror.getCursor();
mde.codemirror.replaceRange(emoji.i, { line, ch }, { line, ch });
}
</script>
<template>
<div>
<textarea
ref="contentArea"
v-model="content"
rows="5"
placeholder="markdown形式で説明を記述できます。"
maxlength="300"
/>
<EmojiPicker
:native="true"
class="emoji-picker"
v-if="displayEmojiPicker"
@select="onSelectEmoji"
/>
</div>
</template>
<style scoped>
.emoji-picker {
position: absolute;
bottom: 20px;
right: 20px;
}
</style>
以下のような動きになります。
参考リンク
- https://github.com/Ionaru/easy-markdown-e%E2%89%88ditor
- https://github.com/delowardev/vue3-emoji-picker

コメント