トップ/記事一覧

Vue3 で Textarea から Control+Enter / Command+Enter どちらでも送信できるようにする

📆2022/08/15🔖 Vue.js

自作の Chrome 拡張 Fast Notion Chrome Extension に、

  • Enter で改行
  • Windows の場合は Control+Enter で送信
  • Mac の場合は Command+Enter で送信
  • のような機構を組み込んだ実装メモ。Slack とかでよく使われているあの入力・送信 UI を Vue.js で実装した。

    🐈

    まず、Vue.js には v-on というディレクティブが存在する。省略記法で @ を使っても書ける。@click とかはよく使う。ユーザーの入力を監視して、入力をトリガーに処理をさせることができる。今回の場合はキーボードの操作なので、keyupkeydown を使用する。keyup は文字通りキーボードを叩いて離した瞬間に発火し、keydown はこちらも文字通りキーボードを押下した瞬間に発火する。

    (Vue3 公式ドキュメント) https://v3.ja.vuejs.org/api/directives.html#v-on

    ドットでつなげることで、どのキーを押下したら発火させるかを template 層で記述することができる。今回は Enter キーを押したときにイベントを発火させたいので、以下のように記述する。Control+Enter / Command+Enter どちらでも送信したいので、その処理は js 側に任せることにして、ここでは Enter を押下した瞬間のディレクティブのみ登録しておく。

    JavaScript

    <textarea @keydown.enter="handleKeydownEnter" />

    これだけだと、Enter だけを押したときに毎回処理が実行されてしまうので、Enter 押下時に同時押しされているかどうかを判定する必要がある。イベントハンドラは引数で KeyboardEvent というオブジェクトを受け取る。これの中には、key というプロパティが含まれており、どのキーが押されたかが詰まっている。今回は Enter を押してイベントハンドラが呼ばれているので、key には Enter という文字列が入っている。

    また、KeyboardEvent には key 以外にも、ctrlKeymetaKey という boolean プロパティが存在する。これは、Ctrl キーが入力されているか、Meta(Mac だと Command)キーが入力されているかを表す boolean 値である。

    (MDN のドキュメント)https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent

    今回で言うと、Enter キーが押された判定は v-on / @ ディレクティブでおこない、同時押しかどうかの判定は KeyboardEvent 内の ctrlKeymetaKey の真偽値で判定する。(Enter が押された判定も、js 側に寄せることも可能だとは思うが、そこはお好みで)

    実装的には以下のような感じになった。

    JavaScript

    const handleKeydownEnter = (e: KeyboardEvent) => { // 同時押ししているキーが、Ctrl キーでも Meta(Command) キーでもない場合は何もしない if (!e.ctrlKey && !e.metaKey) return; // 処理 };

    🐈

    記述量自体は数行で済んだのだが、正直けっこう苦戦した。

    Vue.js で同じことをしたい方の参考になれば幸いです。