【Vue.js】v-onや@アットマークの使い方を実例で解説|イベントハンドラ、イベントオブジェクト($event)、イベント修飾子とは何か?

vue-js-prograshi(プロぐらし)-kv Vue.js
記事内に広告が含まれていることがあります。
[PR]

Vue.jsではボタンやキーをクリックしたときに、指定したイベント(処理)を実行するイベントハンドラをとても簡単に実装することができます。

ここでは、v-onの使い方を実例を交えて解説しています。

またイベントの詳細情報を取得するイベントオブジェクト($event)や、イベントに機能を追加するイベント修飾子の使い方も実例で紹介しています。


イベントの呼び出し方(v-onの使い方)

v-onディレクティブを使用することで、タグにクリックイベントなどのイベントを設定することができます。

設定方法は2種類あります。

v-onのイベント設定方法
  1. 処理をインラインに記述する(HTML上の処理を記述する)
  2. Vue.jsに作成した処理をHTML上で呼び出す

処理をインラインに記述する(HTML上の処理を記述する)場合、HTML上の記述は次のようになります。

<タグ名 v-on:イベント名="JavaScript式" >

Vue.jsに作成したメソッドをHTML上で呼び出す場合は次のようになります。

<タグ名 v-on:イベント名="メソッド名" >


インラインメソッドハンドラとメソッドイベントハンドラの違い

上記2つの呼び出し方にはそれぞれ「インラインメソッドハンドラ」と「メソッドイベントハンドラ」という名前がついています。

処理をインラインに記述する(HTML上の処理を記述する)方法を「インラインメソッドハンドラ」と呼びます。記述する処理はJavaScript式である必要があります。

一方、Vue.jsに作成した処理をHTML上で呼び出す方法を「メソッドイベントハンドラ」と呼びます。

どちらも違いは記述方法の違いだけなので、名称にこだわる必要はほぼありません。(カタカナで長くて覚えづらいです)


v-onの省略標記「@」

なお、v-onディレクティブはVue.jsで多用する処理のため簡単に記述する省略形が用意されています。

「v-on:」と「@」がイコールになります。

v-on:イベント名

 ↓ 省略標記

@イベント名

5文字を1文字の記号で記述できるので、基本的には「@」を使います。


インラインメソッドハンドラの実例(HTML上に直接記述)

HTML上にインラインでJavaScript式を記述して、処理を実行することができます。

簡単な処理の場合に有効です。

※処理が複雑になる場合は、Vue.jsにメソッドを別途記述してメソッドイベントハンドラとして呼び出す必要があります。

v-on:イベント"javascript式"


実例

ボタンをクリックする毎に表示数値に1を加算するイベントを作成します。

ある要素に1追加するには「++」を使用します。

Vue.jsのコード(.jsファイル)

Vue.jsにはcounterというプロパティを設定し、初期値を0とします。

var app = new Vue({
    el:'#app',
    data:{
        counter:0
    }
})


HTMLのコード(.htmlファイル)

<body>
    <div id="app">
        <div>
            ■インラインイベントハンドラ

            <p> 数値:{{ counter }} </p>
            <button @click="counter++">+1</button>
        </div>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>

{{ counter }}マスタッシュ構文を使って、プロパティcounterの値をブラウザに表示します。

<button @click="counter++">+1が画面上に表示するボタンです。「+1」と書かれたボタンを表示して、クリックするたびにプロパティcounterの値にプラス1します。


ブラウザの表示

デフォルトは次のようになっています。

 ↓ 「+1」ボタンをクリック

クリックする度にプロパティnumberの値が+1されていきます。


メソッドイベントハンドラの実例(HTML上でメソッドを呼び出す)

次に、Vue.jsに作成したメソッドをクリックイベントで呼び出す処理の例です。

メソッドは次のように、Vue.jsのmethodsオブジェクトの中に作成します。

    methods:{
        メソッド名: function(){
            処理
        }
    }

HTML上で呼び出すときは、v-onディレクティブの値にメソッド名を指定します。

<タグ名 v-on:イベント名="メソッド名" >


実例

Vue.jsのコード(.jsファイル)

Vue.jsにはcounterというプロパティを設定し、初期値を0とします。addOneという名前のメソッドを作成します。

var app = new Vue({
    el:'#app',
    data:{
        counter:0
    },    
    //メソッドイベントハンドラ
    methods:{
        addOne: function(){
            this.counter++
        }
    }
})
thisとは何か?

メソッドの中でVue.jsで設定したdataオブジェクトのプロパティを呼び出すときは this.プロパティ名とします。

VueをJavaScriptファイルの中に記述するため、JavaScriptとして定義した変数とVueで定義した変数を区別するためのものです。


HTMLのコード(.htmlファイル)

<body>
    <div id="app">
        <div>
            ■メソッドイベントハンドラ

            <p> 数値:{{ counter }} </p>
            <button @click="addOne">+1</button>
        </div>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>

{{ counter }}マスタッシュ構文を使って、プロパティcounterの値をブラウザに表示します。

<button @click="addOne">+1が画面上に表示するボタンです。「+1」と書かれたボタンを表示して、クリックするたびにaddOneメソッドが実行されます。


ブラウザの表示

デフォルトは次のようになっています。

 ↓ 「+1」ボタンをクリック

クリックする度にプロパティnumberの値が+1されていきます。


メソッドイベントハンドラに引数を渡す方法

Vue.jsに作成したメソッドが引数を必要とする場合は、メソッド名の後ろに( ) をつけて引数を渡します。

v-on:click="イベントハンドラ名(引数)"


実例

例として、引数で渡した文字列を画面上に表示する処理を作成します。

クリックイベントが発火すると以下の処理を実行します。

  1. 引数で「受け渡しに成功!」という文字列をメソッドに渡す。
  2. プロパティに代入し、マスタッシュ展開で画面上に表示する。

Vue.jsのコード(.jsファイル)

Vue.jsにはmessageという空のプロパティと、argFuncというメソッドを作成します。

var app = new Vue({
    el:'#app',
    data:{
        message: ''
    },
    methods:{
        //引数をmessageに代入するメソッド
        argFunc: function(arg1){
            this.message = arg1
        }
    }
})

argFuncメソッドが実行されると、messageプロパティに渡された引数のデータを代入します。

HTMLのコード(.htmlファイル)

<body>
    <div id="app">
        <div>
            <p>■イベントハンドラの引数受け渡し</p>

            <p>引数:{{ message }}</p>
            <button @click="argFunc('受け渡しに成功!')">クリック</button>
        </div>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>

<button @click="argFunc('受け渡しに成功!')"> により、ボタンクリックでargFuncメソッドが発火します。引数には「受け渡しに成功!」という文字列が入っています。


ブラウザの表示

デフォルトは次のようになっています。

 ↓ボタンクリック

指定した引数が渡されて画面上に表示されます。


イベントオブジェクトとは何か?$eventの使い方

イベントオブジェクト($event)とは何か?

イベントハンドラでメソッドを実行するとき、イベント処理の詳細が入ったデータを受け渡しすることができます。

HTML側のイベントハンドラのメソッドの引数に$eventを指定すると、この中にイベントに関するデータ入ります。

どの要素がクリックされたか、画面上のx座標、y座標の位置はどこか、親タグは何か、テキストは何が記載されているかなど、データ量は非常に大量です。(詳しくは後述)

HTML側のイベントハンドラのメソッドの引数の中で$eventを何番目に記述するかの指定はありません。1番目でも最後でも機能します。

Vue.jsのメソッドで受け取るときは同じ順番の引数にデータが入ります。


イベントオブジェクト($event)の設定方法

メソッド発火時に引数でイベントオブジェクト($event)のみを渡す場合、HTML側の記述は以下のようになります。

<タグ @click="メソッド名($event)">  </終了タグ>

Vue.js側では任意の引数名を指定すると、その中にイベントデータが入ります。

引数名はeventか省略したeを使うことが一般的です。

    methods:{
        メソッド名: function(e){
      処理
        }
    }



引数が1つ以上の場合

$event以外にもメソッドに渡す引数がある場合は以下のように記述します。

<タグ @click="メソッド名($event, 引数名1, 引数名2,,,,)">  </終了タグ>

上記の場合$eventを1つ目の引数で渡すため、メソッドでも$event情報の受け取りは1つ目の引数になります。($eventを2番目や最後に記述する場合はメソッドの引数もそれに合わせます)

    methods:{
        メソッド名: function(event, 引数名1', 引数名2',,,){
      処理
        }
    }


イベントオブジェクトの中身の参照方法

全てのデータを参照する方法

イベントオブジェクトの中身を全て参照したいときは、console.logで$eventが入った引数をそのまま参照します。

    methods:{
        メソッド名: function(event, 引数名1', 引数名2',,,){
      console.log(event)
        }
    }

コンソールには次のようなデータが表示されます。

まだまだ続く。
注意点

console.logではなく、プロパティに$eventの内容を代入して表示すると、[object PointerEvent]しか表示されません。


指定したデータを参照する

$eventが入った変数に、取得したいプロパティ名を指定することでデータを絞り込むことができます。

イベントオブジェクトのデータが入った変数.プロパティ.プロパティ...


▼実例

    methods:{
        メソッド名: function(event, 引数名1', 引数名2',,,){
            console.log(event.target.tagName)
            console.log(event.target.innerHTML)
            console.log(event.target.type)
            console.log(event.screenX)
            console.log(event.screenY)
        }
    }

コンソールの表示は次のようになります。

なお、これらの個々のデータであれば、Vue.jsのプロパティに代入することも可能です。

var app = new Vue({
    el:'#app',
    data:{
        message: ''
    },
    methods:{
        argFunc: function(event){
            this.message = event.target.innerHTML
        }
    }
})


html上に出力する方法

イベントオブジェクトをHTML上に出力する場合は、イベントオブジェクトのデータをプロパティに代入する必要があります。

HTML上ではマスタッシュ展開を使い、{{ イベントオブジェクト.プロパティ }}とします。

<body>
    <div id="app">

        <div>
            ■イベントオブジェクト
            <p>{{eventObject}}</p>
            <p>タグ名:{{eventObject.target}}</p>
            <p>x座標:{{eventObject.screenX}}</p>
            <p>y座標:{{eventObject.screenY}}</p>
        </div>
       <button @click="addOne">+1</button>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script src="script.js"></script>
</body>
var app = new Vue({
    el:'#app',
    data:{
        //インラインイベントハンドラ(javascript式)
        counter:0,

        //イベントオブジェクトを格納するプロパティ
        eventObject: ''

    },
    //メソッドイベントハンドラ
    methods:{
        addOne: function(event){
            this.counter++

            //イベントオブジェクトの代入          
            this.eventObject = event
        }
    }
})


 ブラウザの表示

デフォルトの状態

 ↓ ボタンクリック


イベント修飾子

v-onイベントはイベント修飾子と呼ばれる特定のメソッドを追加することで、DOMイベントの振る舞いを変更することができます。

v-on:click.イベント修飾子 = "メソッド名"

例えば、クリックイベントを初回の1回のみ実行し、2回目以降は実行しない場合は「.once」を使います。

イベント修飾子のメリット

・methodsオプション側ではなく、htmlで処理を変更できる。
・設定したり、外したりが簡単。

主なイベント修飾子

イベント修飾子概要
.op設置したハンドラは実施するが、親要素のハンドラは実行しない
.preventハンドラを実施するが、次の動作をしない(リンク先に飛ぶなど)
.captureキャプチャモードで実行。最上位の親要素から順にハンドラを適用していく
.selfイベント発生元が要素実親の場合にだけ実行
.onceイベントハンドラを1回だけ実行
.leftマウスの左クリック時のみハンドラを呼び出す
.passivepassiveモードを有効化


以下で主要なイベント修飾子を紹介します。


.once

イベントハンドラを1回のみ実行する。

v-on:イベント名.once="イベントハンドラ名(引数)"

実例

ボタンクリックで初回クリック時のみ現在時刻を表示するプログラムは以下のようになります。(比較用にonceを設定していないボタンも設置しておきます)

  • 現在時刻は new Date()で作成できます。
  • .toLocaleString()でメソッドで秒以下の情報をカットする。

HTML上ではマスタッシュ展開を使い、{{ イベントオブジェクト.プロパティ }}とします。

<body>
    <div id="app">
            <p>イベント修飾子:.once</p>
            <p>現在時刻:{{ nowTime }}</p>

            <button v-on:click="currentTime">通常</button>
            <button v-on:click.once="currentTime">.once</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
var app = new Vue({
    el:'#app',
    data:{
        //現在時刻の格納
        nowTime: ''
    },
    methods:{
        //イベント修飾子 .once
        currentTime: function(){
            this.nowTime = new Date().toLocaleString()
        }
    }
})


 ブラウザの表示

デフォルトの状態

 ↓ .onceボタンをクリック

「通常」ボタンをクリックすると時刻が更新されますが、「.once」ボタンはこれ以上押しても何も変化しません。


.prevent

.prevent修飾子を使うと、イベントハンドラのみ実行し、要素のアクションを実行しないようにすることができます。

v-on:イベント名.prevent="イベントハンドラ名(引数)"


実例

例えば、aタグに.preventを使ったイベントを設定すると、メソッドは実行するものの、リンク先には飛ばないといった処理ができます。

例として、現在時刻を表示するが、リンクは非活性にするプログラムは以下のようになります。参考に、.preventをつけない場合のイベントハンドラも併設しておきます。

HTML上ではマスタッシュ展開を使い、{{ イベントオブジェクト.プロパティ }}とします。

<body>
    <div id="app">
            <p>イベント修飾子:.prevent</p>
      
            <p>現在時刻:{{ nowTime }}</p>
            <a href="https://jp.vuejs.org/index.html" v-on:click="currentTime">・現在時刻更新しvue公式ページトップにリンク</a><br>
            <a href="https://jp.vuejs.org/index.html" v-on:click.prevent="currentTime">・prevent修飾子がある場合</a>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
var app = new Vue({
    el:'#app',
    data:{
        //現在時刻の格納
        nowTime: ''
    },
    methods:{
        //イベント修飾子 .once
        currentTime: function(){
            this.nowTime = new Date().toLocaleString()
        }
    }
})


 ブラウザの表示

デフォルトの状態

 ↓「prevent修飾子がある場合」をクリック

画面遷移は発生しない。

 ↓「現在時刻更新しvue公式ページトップにリンク」をクリック

.preventがない場合はリンク先へ遷移が発生します。


キー修飾子

キー修飾子とは?

特定のキーコードが押された場合に、イベントハンドラを呼び出す指定ができる「キー修飾子」というものも存在します。

キーから指を話した瞬間にイベントが発火する「keyupイベント」と合わせて使用されることが多いです。もちろんおなじみの「clickイベント」でも使うことができます。


キー修飾子の使い方

v-on:keyup.キー修飾子

つなげることで複数のキーを指定することも可能です(同時押ではなく、or条件です)

v-on:keyup.キー修飾子1.キー修飾子2.キー修飾子3...


キー修飾子の一覧

主なキー修飾子

  • enter
  • tab
  • delete (“Backspace” も拾う(キャプチャする))
  • esc
  • space
  • up
  • down
  • left
  • right


アルファベットのキーを指定する方法

キー番号を指定することでアルファベットを指定することもできます。
例えば、aなら「.65」, cなら「.67」のように指定します。

(参考)キーコード一覧:http://faq.creasus.net/04/0131/CharCode.html


キー修飾子の実例

escape, space, deleteキーのいずれかをクリックすると、入力したテキストを削除するプログラムは以下のようになります。

v-on:keyup.esc.space.delete="clearHandler('clicked escape kye!')"

・inputタグにv-onを設定し、イベントハンドラを設定。
・v-modelで入力値とdataオブジェクトのプロパティを連動させる。

<body>
    <div id="app">
        <div>
            <p>キー修飾子</p>
            <p>esc, space, deleteキーのどれかをクリックすると、入力したテキストを削除します。</p>

            <input type="text" v-on:keyup.esc.space.delete="clearHandler('削除しました')" v-model="inputText">
            <p>{{message}}</p>

        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
var app = new Vue({
    el:'#app',
    data:{
        //引数の受け渡し
        inputText: '',
        message: '',
    },
    methods:{
        //キー修飾子
        clearHandler: function(text){
            this.inputText = ""
            this.message = text
        }
    }
})


 ブラウザの表示

デフォルトの表示

 ↓ 「aaaa」と入力

↓ Delキーをクリック



システム修飾子

キー修飾子と似た修飾子に「システム修飾子」があります。これは、ctrlキーなどシステム系と合わせてイベントハンドラを呼び出す修飾子です。

公式ページ

システム修飾子の一覧

  1. .ctrl
  2. .alt ※windowsのみ
  3. .shift
  4. .meta

.meta修飾子とは?
使用しているOSにより異なるキーをクリックしたことになる修飾子です。
・Macの場合: コマンドキー(⌘)
・Windowsの場合: ウィンドウキー(⊞)


システム修飾子の実例

shiftキーを押しながらクリックしたときのみ、アラートを表示するプログラムは次のようになります。

・inputタグにv-onを設定し、イベントハンドラを設定。
・v-modelで入力値とdataオブジェクトのプロパティを連動させる。

<body>
    <div id="app">
        <div>
            <p>システム修飾子</p>
            <p @click.shift="showAlert">
              ▶︎shift押しながらこのテキストをクリック
            </p>

        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
var app = new Vue({
    el:'#app',
    methods:{
        showAlert: function(){
            alert('shiftキーを押しながらクリックしました')
        }
    }
})


 ブラウザの表示

デフォルトの表示

 ↓ shiftキーを押しながらクリック

他のキーや、何もキーを押さずにクリックした場合は何も起こりません。


マウスボタンの修飾子

マウスボタンのクリックによってもイベントハンドラを操作できるマウスボタン系の修飾子もあります。

マウスボタンの修飾子一覧

  1. .left
  2. .right
  3. .middle

.leftと.rightはキー修飾子と共通です。キーボードでもマウスでもどちらでも反応します。.middleはマウスのみです。

公式ページ


確認用ソースコード

参考までに上記の処理をひとまとめにした確認用のソースコードを記載しておきます。

▼ブラウザの表示


▼コード

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>handler</title>
</head>
<body>
    <div id="app">
        <div>
            ■インラインイベントハンドラ
            <p> 数値:{{ counter }} </p>
            <button v-on:click="counter++">+1</button>
        </div>

        <hr>

        <div>
            ■メソッドイベントハンドラ
            <p> 数値:{{ counter }} </p>
            <button v-on:click="clickHandler">+1</button>
        </div>

        <hr>

        <div>
            ■イベントオブジェクト
            <p>{{eventObject}}</p>
            <p>タグ名:{{eventObject.target}}</p>
            <p>x座標:{{eventObject.screenX}}</p>
            <p>y座標:{{eventObject.screenY}}</p>
        </div>

        <hr>

        <div>
            ■イベントハンドラの引数受け渡し
            <p>引数:{{ message }}</p>
            <button v-on:click="argument('受け渡しに成功!')">クリック</button>
        </div>

        <hr>

        <div>
            ■イベントハンドラの引数とイベントオブジェクトの受け渡し
            <p>引数:{{ message }}</p>
            <p>イベントオブジェクト: {{eventObject}}</p>
            <button v-on:click="eveArg($event, '受け渡しに成功!')">クリック</button>
        </div>

        <hr>

        <div>
            ■イベント修飾子<br>
            .once
            <p>現在時刻:{{ nowTime }}</p>
            <button v-on:click="currentTime">通常</button>
            <button v-on:click.once="currentTime">.once</button>

            <br><br>
            .prevent
            <p>現在時刻:{{ nowTime }}</p>
            <a href="https://jp.vuejs.org/index.html" v-on:click="currentTime">現在時刻更新しvue公式ページトップにリンク</a><br>
            <a href="https://jp.vuejs.org/index.html" v-on:click.prevent="currentTime">prevent</a>

        </div>

        <hr>

        <div>
            ■キー修飾子<br>
            esc, space, deleteキーをクリックすると、入力したテキストを削除します。
            <input type="text" v-on:keyup.esc.space.delete="clearHandler('cliked clear key!')" v-model="message">
            <p>{{message1}}</p>

            <br>


            ■システム修飾子<br>
            <p v-on:click.shift="showAlert">
                ▶︎shift押しながらこのテキストをクリック
            </p>

        </div>

        <hr>

        <div>
            ■省略記法<br>
            <p @click.65="showAlert2">
                ▶︎aを押しながらこのテキストをクリック
            </p>

        </div>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
</html>
var app = new Vue({
    el:'#app',
    data:{
        //インラインイベントハンドラ(javascript式)
        counter:0,

        //イベントオブジェクト
        eventObject: '',

        //引数の受け渡し
        message: '',
        message1: '',
        //現在時刻の格納
        nowTime: ''
    },
    //メソッドイベントハンドラ
    methods:{
        clickHandler: function(event){
            this.counter++

            //イベントオブジェクト
            this.eventObject = event
            console.log(event)
            console.log(event.target)
            console.log(event.target.tagName)
            console.log(event.target.innerHTML)
            console.log(event.target.type)
            console.log(event.screenX)
            console.log(event.screenY)
        },

        //引数の受け渡し
        argument: function(arg1){
            this.message = arg1
        },

        //イベントオブジェクトと引数の受け渡し
        eveArg: function($event, arg1){
            this.message = arg1
            this.eventObject = $event
        },

        //イベント修飾子
        currentTime: function(){
            this.nowTime = new Date().toLocaleString()
        },

        //キー修飾子
        clearHandler: function(text){
            this.message = ""
            this.message1 = text
        },
        //システム修飾子
        showAlert: function(){
            alert('shiftキーを押しながらクリックしました')
        },

        //省略記法
        showAlert2: function(){
            alert('aを押しながらクリックしました')
        }
    }
})
タイトルとURLをコピーしました