4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.js イベントハンドリング

Last updated at Posted at 2020-05-08

#Vue.js イベントハンドリング

前回の記事はこちら
Vue.js 条件付きレンダリング

##インラインイベントハンドラ
jsfiddleで実際に記述しながら読むことをおすすめします。

v-onディレクティブを使うとDOMイベントの購読、イベント発火時のjavascriptの実行が可能です。
クリックボタンを押す回数をカウンターにしてみましょう

index/html
<div id="app">
  
<p>
  {{ counter }}
</p>

<button v-on:click="counter ++">
  click
</button>
  
</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
  el:'#app',
  data:{
    counter: 0
  }
})

実行結果
Image from Gyazo

v-onディレクティブで補足されたcounterに属性として記述された処理(++)が実行されています。

##メソッドイベントハンドラ
上記では属性の値に処理を記述しましたが複雑な処理を記述するには限界があります。
メソッドイベントハンドラを使ってメソッド名として記述してみましょう

以下のように書き直します

index/html
<div id="app">
  
<p>
  {{ counter }}
</p>

<button v-on:click="clickHandler">
  click
</button>
  
</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
	el:'#app',
  data:{
    counter: 0
  },
  methods:{
    clickHandler:function(){
      this.counter++
    }
  }
})

実行結果
Image from Gyazo

動作は同じですがメソッドオプションを使うため
処理が複雑になってもhtmlの見通しが悪くなることはありません。

##イベントオブジェクトの参照
イベントハンドラのメソッドに引数を指定しイベントオブジェクトを取得することができます。

上記のカウンターからイベントオブジェクトを参照し
コンソールに表示してみましょう。

index/html
<div id="app">
  
<p>
  {{ counter }}
</p>

<button v-on:click="clickHandler">
  click
</button>
  
</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
	el:'#app',
  data:{
    counter: 0
  },
  methods:{
    clickHandler:function(event){
      this.counter++
      console.log(event) //イベントの取得
      console.log(event.target.tagName) //タグの取得
      console.log(event.target.innerHTML) //htmlの取得
      console.log(event.target.type) //タイプの取得
    }
  }
})

実行結果
Image from Gyazo
イベント、タグ、html、タイプをコンソールに表示ができています。

##イベントハンドラに引数を渡す
clickHandlerメソッドの引数に文字列を渡して
クリックで表示してみましょう

index/html
<div id="app">
  
<p>
  {{ message }}
</p>

<button v-on:click="clickHandler('Vue.js')">
  click
</button>

<pre> <!--デバッグ用-->
  {{$data}}
</pre>
  
</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
	el:'#app',
  data:{
    message:''
  },
  methods:{
    clickHandler:function(message){
      this.message = message
    }
  }
})

実行結果
Image from Gyazo

クリックによってclickHandlerメソッドで引数として渡された
Vue.jsの文字列がdataオプションに格納されて
messageとして表示されました。

##$event
上記では引数で"Vue.js"の文字列を使用しているのでeventの取得ができません。
このようなときは$eventを引数に明示することでeventが取得できます。

以下を記述してみましょう

index/html
<div id="app">
  
<p>
  {{ message }}
</p>

<button v-on:click="clickHandler($event, 'Vue.js')">
  click
</button>

<pre>
  {{$data}}
</pre>
  
</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
  el:'#app',
  data:{
    message:''
  },
  methods:{
    clickHandler:function($event,message){
      this.message = message
      console.log($event)
    }
  }
})

実行結果
Image from Gyazo

引数として文字列とeventを渡すことができています。

##イベント修飾子
v-onのためにクリックなどのDOMイベントの振る舞いを変更する修飾子が用意されています

代表的な修飾子は以下のとおりです。
.stop イベントの親要素への伝搬を中止
.prevent イベント規定の操作をキャンセル
.capture イベントハンドラをキャプチャモードで動作
.self イベント発生元が要素実親の場合だけ実行
.once イベントハンドラを1回だけ実行
.passive passiveモードを有効化

.onceを例にして記述してみましょう。
ボタンをクリックしたら現在時刻を取得するが2回目以降は動作しないプログラムを記述します。

index/html
<div id="app">

<p>
  {{ message }}
</p>

<button v-on:click.once="clickHandler">
  click
</button>
  

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
  el:'#app',
  data:{
    message:""
  },
  methods:{
    clickHandler:function(){
      this.message = new Date().toLocaleTimeString()
    }
  }
})

実行結果
Image from Gyazo

1回目のクリックで現在時刻を取得しますが2回目以降は動作しません。
.once修飾子を外すと押した時刻を何度でも取得できます。

##キー修飾子
キーイベントをフックにして特定のキーコードのキーが押された時のみ
特定のイベントハンドラを呼び出すことができます。

escキーが押されたらテキストの入力がクリアされるように記述してみましょう

index/html
<div id="app">

  <input type="text" v-on:keyup.27="clear" v-model="message">
  <p>
    {{message}}
  </p>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
  el:'#app',
  data:{
    message:""
  },
  methods:{
    clear:function(){
      this.message = ""
    }
  }
})

Image from Gyazo

入力後にescキーを押すことでinputをクリアできています。
キーコード一覧

エスケープキーを以下のように記述することも可能です。

index/html
  <input type="text" v-on:keyup.esc="clear" v-model="message">

また複数設定する場合はドットでつなぎましょう
下記はエスケープキー、スペースキー、↑キーを設定したサンプルです

index/html
  <input type="text" v-on:keyup.esc.space.up="clear" v-model="message">

##システム修飾子
下記のシステム修飾子は対応するキーが押されている時に
処理を行うことができます。

.ctrl ctrlキーが押されているとき
.alt altキーが押されているとき
.shift shiftキーが押されているとき
.meta mac:コマンドキーが押されているとき windows:windowsキーが押されているとき

ctrl + c で入力がクリアされるコードを記述してみましょう

index/html
<div id="app">

<input type="text" v-on:keyup.ctrl.67="clear" v-model="message">

<p>
  {{message}}
</p>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
  el:'#app',
  data:{
    message:""
  },
  methods:{
    clear:function(){
      this.message = ""
    }
  }
})

実行結果

Image from Gyazo

cキーのみ押した場合はcを、ctrl+cキーの場合は入力がクリアされます。

次にdiv要素の文字列をshiftキーを押しながらクリックで
clickHanderメソッドを呼び出しaleartダイアログを表示しましょう

index/html
<div id="app">

<div v-on:click.shift="clickHandler">
  Click me
</div>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
  el:'#app',
  data:{
    message:""
  },
  methods:{
    clickHandler:function(){
      alert('shift + click')
    }
  }
})

実行結果
Image from Gyazo

v-on:cliskディレクティブにシステム修飾子を付加してshift+clickで
clickHandlerメソッドを呼び出しています。

次回はフォーム入力バインディングについてです。
Vue.js フォーム入力バインディング

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?