Vue.jsのイベント回りをちょっと細かめに触る機会がありました。
ガイドを読んで学んだことをまとめます。

ドキュメント

Vue.js > ガイド > イベントハンドリング
https://jp.vuejs.org/v2/guide/events.html

環境

  • Vue.js 2.2.x
  • npm 4.0.x
  • node.js 7.0.x

v-on

イベントをバインドするにはv-onディレクティブです。

1<button v-on:click="[ 何か処理 ]">

v-onは@と省略することができます。 次のコードは先のものと等価です。

1<button @click="[ 何か処理 ]">

Vue.jsを触っているとやたらと@を目にします。
慣れるまでv-onに脳内変換するのが大変です。

イベントの実行

v-on属性の値にJavaScript式を書くことができます。

1<button @click="counter + 1">

関数名を指定することも可能です。

1<button @click="countUp">

関数に引数を与えることも可能です。

1<button @click="countUp(2)">

上記の表現だけで、実にいろいろなことができます。
この辺りが整理できると、無駄のない簡潔なコードを書くことができると思います。

こういった使い方もできるという例を示します。

クリックしたボタンの詳細を表示する

1<div v-for="item in items">
2  <button @click="detail = item">
3</div>
4
5<div id="detail" v-if="detail != null">
6  {{ detail.name }}
7  <!-- 素晴らしい実装 -->
8</div>

子コンポーネントから親コンポーネント$emitを飛ばす

1<button @close="$emit('close')">

いやー、無駄がないですね。 美しい、、、

修飾子

v-onには大変便利な修飾子がいくつも実装されています。

例によってドキュメントから引用いたします。

 1<!-- クリックイベントの伝搬が止まります -->
 2<a v-on:click.stop="doThis"></a>
 3<!-- submit イベントによってページがリロードされません -->
 4<form v-on:submit.prevent="onSubmit"></form>
 5<!-- 修飾子は繋げることができます -->
 6<a v-on:click.stop.prevent="doThat"></a>
 7<!-- 値を指定せず、修飾子だけ利用することもできます -->
 8<form v-on:submit.prevent></form>
 9<!-- イベントリスナーを追加するときにキャプチャモードで使います -->
10<!-- 言い換えれば、内部要素を対象とするイベントは、その要素によって処理される前にここで処理されます -->
11<div v-on:click.capture="doThis">...</div>
12<!-- event.target が要素自身のときだけ、ハンドラが呼び出されます -->
13<!-- 言い換えると子要素のときは呼び出されません -->
14<div v-on:click.self="doThat">...</div>

上のコードは次より引用
https://jp.vuejs.org/v2/guide/events.html#イベント修飾子


5年前には「 とりあえずデフォルト動作とバブリングは禁止しておけばOK! 」と、ことあるごとに次のコードを書いてしまっていました。

1$('#hoge').click(function(event) {
2    event.preventDefault();
3    event.stopPropagation();
4});

Vue.jsでは修飾子で処理できるので、意図が明確ですし、記法も簡潔ですねー。

1<button @click.stop.prevent>

キー修飾子

Vue.jsではキーイベントで使いやすいエイリアスが用意されています。

  • enter
  • tab
  • delete (“Delete” と “Backspace” キー両方をキャプチャします)
  • esc
  • space
  • up
  • down
  • left
  • right

次より引用
https://jp.vuejs.org/v2/guide/events.html#キー修飾子

5年前はこんな関数を実装し、キーコードごとに処理分けをしていました。
キーコードを調べなくてはなりませんし、直感的ではありません。

 1var keyDown = function(e) {
 2  if (e.keyCode == 9  /* tab   */) {
 3    // 何か処理
 4  }
 5  if (e.keyCode == 13 /* enter */) {
 6    // 何か処理
 7  }
 8  // あれ、キーコードはあってる?
 9  if (e.keyCode == 37 /* up */) {
10    // 何か処理
11  }
12  : // 延々と続く
13};

Vueでは、一部キーを修飾子でフォローしております。
極端ですが、次のようにキーイベントを並べることもできます。

1<div
2  @keydown.enter="keyEnter"
3  @keydown.tab="keyTag"
4  @keydown.up="keyArrow(-3)"
5  @keydown.down="keyArrow(3)"
6  @keydown.left="keyArrow(-1)"
7  @keydown.right="keyArrow(1)"
8>

コードを覚えたり調べたりする必要がないというのは、大変素晴らしいです。


上の例のようにやたらとキーイベントを並べたりすると、それだけイベントリスナが登録されてしまうのかどうか。

そこは調べきれていないため、もしご存知の方は教えてくださると助かります。

その他の修飾子

修飾子 説明 バージョン
.ctrl Controlキーに対応 2.1.0
.alt Altキーに対応 2.1.0
.shift Shiftキーに対応 2.1.0
.meta Mac: コマンドキー(⌘) Win: ウィンドウキー(⊞) 2.1.0
.left マウス左ボタンに対応 2.2.0
.right マウス右ボタンに対応 2.2.0
.middle マウス中ボタンに対応 2.2.0

次より引用
https://jp.vuejs.org/v2/guide/events.html#修飾子キー
https://jp.vuejs.org/v2/guide/events.html#マウスボタンの修飾子

おわりに

Vue.jsでイベントを購読するには v-onディレクティブ であると、これだけ知っていればとりあえず使えます。
これに加えて便利な修飾子を知るともっと簡単な実装でイベントを実装できますよ、という内容でした。

楽しい開発ライフをお過ごしください。