[Vue入門] イベントハンドリングとメソッド

イベントの扱い

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

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

  1. インラインハンドラー: イベント発火時に実行されるインライン JavaScript 式 (これはネイディブの onclick 属性に似たものです)
  2. メソッドハンドラー: コンポーネント上で定義されたメソッドを示すプロパティ名またはパス

インラインハンドラー

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

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

プレイグラウンドで試す

メソッドハンドラー

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

例:

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

プレイグラウンドで試す

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

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

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

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

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

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

プレイグラウンドで試す

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

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

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

<!-- インラインでアロー関数を使用する場合 -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
  Submit
</button>
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
<!-- クリックイベントの伝搬は停止します -->
<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 メソッドのオプション を反映します:

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

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

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

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

TIP

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

キー修飾子

イベントの購読#

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

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

  1. インラインハンドラー: イベント発火時に実行されるインライン JavaScript 式 (これはネイディブの onclick 属性に似たものです)
  2. メソッドハンドラー: コンポーネント上で定義されたメソッドを示すプロパティ名またはパス

インラインハンドラー

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

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

プレイグラウンドで試す

メソッドハンドラー

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

例:

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

プレイグラウンドで試す

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

参照: イベントハンドラーの型付け 

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

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

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

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

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

プレイグラウンドで試す

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

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

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

<!-- インラインでアロー関数を使用する場合 -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
  Submit
</button>
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
<!-- クリックイベントの伝搬は停止します -->
<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 メソッドのオプション を反映します:

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

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

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

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

TIP

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

キー修飾子(モディファイヤー)

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

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

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

<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」と表示されます。

例:

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

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

TIP

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

.exact 修飾子

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

<!-- これは  たとえ 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

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

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

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

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

<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」と表示されます。

例:

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

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

TIP

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

.exact 修飾子

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

<!-- これは  たとえ 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

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