【写真とコード付き】Vue.jsで書くイベント処理の方法【４選】

<br>

## はじめに
この記事は**Vue.jsの基本は抑えられている程**で、話を進めていきます。もしVue.jsを初めて触ると言う方は、こちらの記事を参照していただければと思います。

⬇️**【写真とコード付き】Vue.jsの構築から基本的な書き方まで1から解説【超初心者向け】**
https://qiita.com/yuki4839/items/62f40564e3f4c8dbfc51
<br>

では今回は、Vue.jsで**イベントの発火**によく使用されるであろう、`v-on` ディレクティブについて、詳しく解説していきます。

早速いきましょう。
<br>
<br>

## 実行環境
使用ツール、デバイスはこちら

<ul>
  <li>Google chrome</li>
  <li>Mac OS Catalina</li>
  <li>Visual Studio Code</li>
</ul>
<br>

また今回使用するディレクトリ階層はこちら。

```html:ディレクトリ階層
─ root(任意のディレクトリ)
│
├─ index.html
│
├─ css
│   └ style.css
│
└─ js
    └ main.js
```
<br>

各ファイルの初期値はこちら。

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <link rel="stylesheet" href="./css/style.css">
</head>

<body>

  <div id="web">
    <p>
      {{ context }}
    </p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script src="./js/main.js"></script>
</body>

</html>
```

```css:style.css
/* 出力結果を見やすくするためのスタイルです */
body {
  background-color: #add8e6;
}

#web {
  background-color: #fff;
  margin: 20px;
  padding: 20px;
  width: 300px;
}
```

```js:main.js
const web = new Vue({
  el: '#web',
  data: {
    context: `Hello Vue.js!`
  }
})
```
<br>

現時点での出力結果はこちら。

![スクリーンショット 2020-12-12 21.13.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/fb3335b5-8937-d54c-f34d-0c96d64eaff6.png)
<br>
<br>

## v-on
まず `v-on` ディレクティブについて簡単に説明すると、ボタンなどがクリックされた時に、**何らかのイベントを発生させる事ができるディレクティブ**になります。
<br>

### クリック処理
最初は `v-on` ディレクティブで、最も基本的な処理についてです。文章で伝えるよりも、コードを見て理解してもらうのが早いと思いますので、まずは実際のコードをご覧ください。

```html:index.html
<!-- headタグ省略 -->
<body>

  <div id="web">
    <button v-on:click="click">
      Click!
    </button>
    <p>
      {{ time }}
    </p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script src="./js/main.js"></script>

</body>
```

```js:main.js
const web = new Vue({
  el: '#web',
  data: {
  	time: ''
  },
  methods: {
  	click: function() {
      this.time = new Date().toLocaleString();
    }
	}
})
```
<br>

ポイントは、buttonタグに `v-on:click` の属性がある事と、js側では属性値に対応した `function()` が定義されている点です。

動作内容としては、ボタンがクリックされると、`click function()` が動作し、中の処理が実行されます。(今回なら現在時刻を出力。)
<br>

では動作確認。
まずデフォルトの表示がこちら。
↓
![スクリーンショット 2020-12-12 21.39.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/a9ba2455-c2e9-3db8-e57e-dcd350064688.png)

次にボタンをクリックした結果がこちら。
↓
![スクリーンショット 2020-12-12 21.41.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/a7e49b5e-823f-059d-c521-1809df0be300.png)
<br>
<br>

### 1度のみの処理
続いて `v-on` ディレクティブで、画面読み込み後に**1度だけ発火させたいイベント処理**の方法です。まずコードはこちら。

```html:index.html
<!-- headタグ省略 -->
<body>

  <div id="web">
    <button v-on:click.once="click">
      Click!
    </button>
    <p>
    {{ time }}
    </p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script src="./js/main.js"></script>

</body>
```

```js:main.js
const web = new Vue({
  el: '#web',
  data: {
    time: ''
  },
  methods: {
    click: function() {
      this.time = new Date().toLocaleTimeString()
    }
  }
})
```

ポイントは `v-on:click` の後に `.once` を記述している点です。これにより、画面読み込み後は1度イベントが発火すると、そのあとは発火しなくなります。
<br>

では動作確認。
まずデフォルトの表示がこちら。
↓
![スクリーンショット 2020-12-12 22.03.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/38743a7a-76c0-449e-f675-6c2347d333c3.png)

次にボタンをクリックした結果がこちら。
↓
![スクリーンショット 2020-12-12 22.03.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/328367c7-927f-ba34-28d5-0ecd5160208c.png)

一見通常のクリック処理と同じですが、このあとボタンを押しても、**画面の読み込みを行わない限り更新はされません。**(先ほどの `.once` なしの記述の場合は、何度も更新する事ができます。)
<br>
<br>

### 引数を利用した処理
続いて `v-on` ディレクティブを使用した属性値に、**引数を渡した際の処理**の方法です。まずはコードはこちら。

```html:index.html
<!-- headタグ省略 -->
<body>

  <div id="web">
    <button v-on:click="clickHandler('Hello Vue.js!')">
      Click!
    </button>
    <p>
    {{ context }}
    </p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script src="./js/main.js"></script>

</body>
```

```js:main.js
const web = new Vue({
  el: '#web',
  data: {
    context: ''
  },
  methods: {
    clickHandler: function(message) {
      this.context = message
    }
  }
})
```

ポイントは `v-on:click属性` の属性値に、**関数名と引数**を設定。そしてボタンがクリックされたら、**js側で用意されていたイベントが発火**と言う仕組みです。

>上記の場合は引数で受け取った値を、そのままcontextに代入しているので、出力結果は引数の値になります。

<br>

では動作確認です。まずデフォルトの表示がこちら。
↓
![スクリーンショット 2020-12-12 21.52.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/d58b0a7c-8c36-7528-f25a-a29adaf96a6b.png)


次にボタンをクリックした結果がこちら。
↓
![スクリーンショット 2020-12-12 21.52.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/02a961e9-5691-1c7b-8723-a113114d1ebc.png)
<br>
<br>

### 省略記法
最後に `v-on` の**省略した書き方**についてです。まずコードはこちら。(jsは先程と同様です。)

```html:index.html
<!-- headタグ省略 -->
<body>

  <div id="web">
    <button @click="clickHandler('Hello Vue.js!')">
      Click!
    </button>
    <p>
    {{ context }}
    </p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <script src="./js/main.js"></script>

</body>
```

```js:main.js
const web = new Vue({
  el: '#web',
  data: {
    context: ''
  },
  methods: {
    clickHandler: function(message) {
      this.context = message
    }
  }
})
```

ポイントは `v-on:` の部分が、`@` に変わった点です。このように**省略して書く事**が可能です。もしプロジェクトで使用する際は、どちらかに統一しておくと、可読性が上がると思われます。
<br>

念のため動作確認。
まずデフォルトの表示がこちら。
↓
![スクリーンショット 2020-12-12 21.52.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/c856ab39-2c6a-bd76-4de1-ce6ec9ee1f58.png)


次にボタンをクリックした結果がこちら。
↓
![スクリーンショット 2020-12-12 21.52.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/9c261872-0d76-1a46-e671-82958f18e325.png)

先程と全く同じ結果が得られました。
<br>
<br>

## まとめ
以上が `v-on` ディレクティブで良く使われるであろう、**イベント処理**の記述方法になります。もう一度まとめておくと、以下の通りです。

<ul>
  <li>クリック処理
    <ul>
      <li>v-on:click="click"</li>
    </ul>
  </li>
  <li>1度だけの処理
    <ul>
      <li>v-on:click.once="click"</li>
    </ul>
  </li>
  <li>引数を利用した処理
    <ul>
      <li>v-on:click="clickHandler('Hello Vue.js!')</li>
    </ul>
  </li>
  <li>省略記法
    <ul>
      <li>@click="clickHandler('Hello Vue.js!')"</li>
    </ul>
  </li>
</ul>
<br>

また補足として、`v-on` ディレクティブは他にも多数の使用方法があります。多くは「これいつ使う？」って感じだったので、今回は紹介しておりませんが、もし興味がある方は公式リファレンスをご参照ください。

イベントハンドリング(Vue.js公式リファレンス)
https://jp.vuejs.org/v2/guide/events.html

最後まで読んでいただき、ありがとうございました！
<br>
<br>
<br>

筆者：yuki｜IT業界のリアルな転職事情など発信｜元トップ営業マン(訪販)→未経験からエンジニア転職へ
Qiita：https://qiita.com/yuki4839
Twitter：https://twitter.com/yukifullstack
<br>