トップ/記事一覧
Vue3 で Textarea から Control+Enter / Command+Enter どちらでも送信できるようにする
📆2022/08/15🔖 Vue.js
自作の Chrome 拡張 Fast Notion Chrome Extension に、
のような機構を組み込んだ実装メモ。Slack とかでよく使われているあの入力・送信 UI を Vue.js で実装した。
🐈
まず、Vue.js には v-on というディレクティブが存在する。省略記法で @ を使っても書ける。@click とかはよく使う。ユーザーの入力を監視して、入力をトリガーに処理をさせることができる。今回の場合はキーボードの操作なので、keyup や keydown を使用する。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 以外にも、ctrlKey や metaKey という boolean プロパティが存在する。これは、Ctrl キーが入力されているか、Meta(Mac だと Command)キーが入力されているかを表す boolean 値である。
(MDN のドキュメント)https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent
今回で言うと、Enter キーが押された判定は v-on / @ ディレクティブでおこない、同時押しかどうかの判定は KeyboardEvent 内の ctrlKey と metaKey の真偽値で判定する。(Enter が押された判定も、js 側に寄せることも可能だとは思うが、そこはお好みで)
実装的には以下のような感じになった。
JavaScript
const handleKeydownEnter = (e: KeyboardEvent) => { // 同時押ししているキーが、Ctrl キーでも Meta(Command) キーでもない場合は何もしない if (!e.ctrlKey && !e.metaKey) return; // 処理 };
🐈
記述量自体は数行で済んだのだが、正直けっこう苦戦した。
Vue.js で同じことをしたい方の参考になれば幸いです。