本文へジャンプ

イベントハンドリング

イベントの購読

v-on ディレクティブを使用することで、 DOM イベントの購読やイベント発火時にいくつかの JavaScript を実行します。これは通常 @ に省略することができます。使い方は v-on:click="handler"、あるいは省略して @click="handler" として使用します。

ハンドラーの値は以下のいずれかを指定します:

  1. インラインハンドラー: イベント発火時に実行されるインライン JavaScript 式(これはネイディブの onclick 属性に似たものです)

  2. メソッドハンドラー: コンポーネント上で定義されたメソッドを示すプロパティ名またはパス

インラインハンドラー

インラインハンドラーは、通常、次のような単純なケースで使用されます:

js
const count = ref(0)
js
data() {
  return {
    count: 0
  }
}
template
<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>

メソッドハンドラー

しかしながら、多くのイベントハンドラーのロジックはより複雑で、インラインハンドラーでは実行できない可能性があります。だからこそ、v-on は呼び出したいコンポーネントメソッドの名前やパスで使用することができます。

例:

js
const name = ref('Vue.js')

function greet(event) {
  alert(`Hello ${name.value}!`)
  // `event` はネイディブ DOM イベントです。
  if (event) {
    alert(event.target.tagName)
  }
}
js
data() {
  return {
    name: 'Vue.js'
  }
},
methods: {
  greet(event) {
    // メソッド内の `this` は、現在、アクティブなインスタンスを示します。
    alert(`Hello ${this.name}!`)
    // `event` はネイティブの DOM イベントです。
    if (event) {
      alert(event.target.tagName)
    }
  }
}
template
<!-- `greet` は上で定義したメソッド名です。 -->
<button @click="greet">Greet</button>

メソッドハンドラーは、トリガーとなるネイティブの DOM イベントオブジェクトを自動的に受け取ります。- 上記の例では、event.target.tagName を通してイベントを発信した要素へアクセスすることができます。

メソッド 対 インライン検出

テンプレートコンパイラーは、v-on の文字列値が JavaScript identifier、あるいはプロパティのアクセスパスとして適切かどうかを検証することで、メソッドハンドラーを検出します。例えば、foofoo.bar さらには foo['bar'] がメソッドハンドラーとして扱われる一方、foo() and count++ はインラインハンドラーとして扱われます。

インラインハンドラー下でのメソッドの呼び出し

メソッドネームに直接束縛する代わりに、インラインハンドラーのメソッドを呼び出すこともできます。これにより、ネイティブイベントの代わりにカスタムの引数をメソッドに渡すことができます。

js
function say(message) {
  alert(message)
}
js
methods: {
  say(message) {
    alert(message)
  }
}
template
<button @click="say('hello')">Say hello</button>
<button @click="say('bye')">Say bye</button>

インラインハンドラーのイベント引数へのアクセス

ときどき、インラインハンドラーでオリジナルの DOM イベントへアクセスが必要になる場合もあります。その場合、特別な $event 変数を使って DOM イベントをメソッドに渡したり、あるいはインライン上でアロー関数を使用します:

template
<!-- 特殊変数 $event を使用する場合 -->
<button @click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>

<!-- インラインでアロー関数を使用する場合 -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
  Submit
</button>
js
function warn(message, event) {
  // これでネイティブイベントにアクセスできるようになりました
  if (event) {
    event.preventDefault()
  }
  alert(message)
}
js
methods: {
  warn(message, event) {
    // これでネイティブイベントにアクセスできるようになりました
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

イベント修飾子

イベントハンドラーの中で event.preventDefault() あるいは event.stopPropagation() を呼び出す必要があるのはよくあることです。たとえメソッド内で簡単に扱うことができるかどうかにかかわらず、メソッドが DOM イベントの詳細を扱うのではなく、純粋にデータロジックに特化したメソッドがより最適です。

この問題を扱うにあたり、Vue は v-on のための イベント修飾子(event modifiers) を提供します。修飾子は、ドット(.)によって示されるディレクティブの接尾辞であることを思い返してください。

  • .stop
  • .prevent
  • .self
  • .capture
  • .once
  • .passive
template
<!-- クリックイベントの伝搬は停止します -->
<a @click.stop="doThis"></a>

<!-- サブミットイベントはもはやページをリロードしません -->
<form @submit.prevent="onSubmit"></form>

<!-- 修飾子は繋げることができます -->
<a @click.stop.prevent="doThat"></a>

<!-- ただの修飾子として使用できます -->
<form @submit.prevent></form>

<!-- event.target が 要素それ自身であるときだけ ハンドラーが呼び出されます-->
<!-- つまり、子要素である場合 -->
<div @click.self="doThat">...</div>

TIP

関連するコードが同じの順番で生成されるため、修飾子を使用するときには順番は重要です。したがって、@click.prevent.self を使うと 要素自身とその子要素に対するクリックのデフォルトアクション に干渉するのに対して、@click.self.prevent は要素自身のクリックのデフォルトアクションにのみに干渉します。

.capture.once、 さらには .passive 修飾子はネイティブ addEventListener メソッドのオプションを反映します:

template
<!-- イベントリスナーを加えるときにキャプチャーモードを使用します。 -->
<!-- つまり、内側の要素をターゲットにしたイベントは               -->
<!-- その要素で操作される前にここで操作されます。                 -->
<div @click.capture="doThis">...</div>

<!-- クリックイベントは最大で 1 度だけ呼ばれます。 -->
<a @click.once="doThis"></a>

<!-- `event.preventDefault()` が含まれる場合、         -->
<!-- スクロールイベントのデフォルト動作(スクロール)は   -->
<!-- `onScroll` が完了するのを待たずに即座に実行されます -->
<div @scroll.passive="onScroll">...</div>

.passive 修飾子は通常、モバイル機器のパフォーマンスの改善のためのタッチイベントリスナーで使用します。

TIP

.passive.prevent を一緒に使わないでください。なぜなら、.passive はブラウザーですでにイベントのデフォルト動作を干渉「しない」ことを示しているからです。それにより、もしそうした場合においてブラウザーが警告を出す可能性が高いからです。

キー修飾子

キーボードイベントを購読しているとき、特定のキーをチェックする必要がある場合があります。キーイベントを購読する際、Vue は v-on あるいは @ にキー修飾子を加えることができます:

template
<!--`submit`は `key` が `Enter`のときにのみ呼ばれます -->
<input @keyup.enter="submit" />

KeyboardEvent.key を介して公開されている有効なキーネームをケバブケースに変換されることで、直接修飾子として使用することができます。

template
<input @keyup.page-down="onPageDown" />

上記の例では、$event.key'PageDown' と等しい場合にのみハンドラーは呼ばれます。

キーのエイリアス

Vue はもっともよく使われるキーのためにエイリアスが提供されます:

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

システムの修飾子

以下の修飾子を使用すると、対応する修飾子が押されたときにのみ、マウスやキーボードのイベントを発火させることができます:

  • .ctrl
  • .alt
  • .shift
  • .meta

注意

Mac キーボードでは、メタキーはコマンドキー(⌘)が使われるのに対して、Windows キーボードでは、メタキーはウィンドウズキー(⊞)が使われます。サンマイクロシステムキーボードでは、メタキーは実線のダイアモンド(◆)がマークとして使われます。特定のキーボード、特に MIT や Lisp マシーンキーボードや、ナイトキーボードやスペースカデットキーボードといった後継機では、メタキーは「META」、または「Meta」と表示されます。

例:

template
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

TIP

修飾子キーは通常のキーとは異なり、keyup イベントと一緒に使用する時は、イベントが発行された時に押されている必要があることに注意してください。言い換えると、ctrl キーを押し続けている間は keyup.ctrl はキーを離した時にのみ発火されます。ctrl キーだけをを解放したとしてもイベントは発火しません。

.exact 修飾子

.exact 修飾子は、イベントを発火するのに必要なシステム修飾子との正確な組み合わせのコントロールを可能にします。

template
<!-- これは  たとえ Alt や Shift キーが押されてたとしても発火されます -->
<button @click.ctrl="onClick">A</button>

<!-- これは Ctrl キーが押され、他のキーが押されてないときだけ発行されます -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- これは システム修飾子が押されてないときだけ発行されます -->
<button @click.exact="onClick">A</button>

マウスボタン修飾子

  • .left
  • .right
  • .middle

これらの修飾子は特定のマウスボタンが発火したイベントを制御するハンドラーを制限します。

イベントハンドリングが読み込まれました