[[📗03 令和はscript setup時代]] < [[📒Vue.jsクエスト]] > [[📗05 状態で広がるセカイ Ref編]]
## Abstract
`@`の由来ご存じですか? そう👂の形からきてるんです(嘘)
## Lesson
[[DOM]]に `@イベント名="関数"` と記述すると、イベントが発生したときに関数の処理を実行します。たとえば以下のコードは、`click`ボタンをクリックしたらアラートが表示されるコードです。
```html
<script setup lang="ts">
const handleClick = () => {
window.alert("clicked!");
};
</script>
<template>
<button @click="handleClick">click</button>
</template>
```
`@`は耳の形に似ています。`@click`は『👂click』というイメージ。clickイベントを聴いている(監視している)と覚えましょう。
`@`は[[v-on (Vue)|v-on]]の糖衣構文です。以下の書き方を短縮したものです。
```html
<script setup lang="ts">
const handleClick = () => {
window.alert("clicked!");
};
</script>
<template>
<button v-on:click="handleClick">click</button>
</template>
```
> [!info]
> イベントの一覧は[[イベントリファレンス]]に記載されています。実際に使うイベントはごく一部ですので、[[📒Vue.jsクエスト]]の中でMissionをこなしていけば習得できるようになっています。
## Missions
### Mission 1
#🙂NORMAL
[[#Lesson]]のコード、以下の部分について
```html
<button @click="handleClick">click</button>
```
`@click="..."`の中身を[[アロー関数 (JavaScript)|アロー関数]]で書き換えてください。
%%
回答例
```
<button @click="() => { handleClick() }">click</button>
```
%%
### Mission 2
#🙂NORMAL
[[#Mission 1]]の回答について、関数名を指定しても、[[アロー関数 (JavaScript)|アロー関数]]に書き換えても期待通り動作する理由を説明してください。
> [!hint]- Hint 1
> `handleClick`と`() => handleClick()`が[[TypeScript]]において、それぞれ何型になるかを考えてみましょう。変数に代入してみるとイメージがわきやすいかも?
> ```ts
> const a1 = handleClick
> const a2 = () => { handleClick() }
> ```
%%
回答例
`@click`には関数型が期待されている。`handleClick`と`() => handleClick()`はどちらも関数型であるため動く。
%%
### Mission 3
#😵HARD
ボタンをクリックすると、ボタンの文字列がアラートとして表示されるコードを書いてください。ただし、`@click`で指定した関数内で呼び出す`window.alert`の引数に定数を指定してはいけません。
%%
回答例
```html
<script setup lang="ts">
const handleClick = (event: MouseEvent) => {
const buttonElement = event.target as HTMLButtonElement;
window.alert(buttonElement.textContent);
};
</script>
<template>
<button @click="handleClick">click</button>
</template>
```
%%
> [!hint]- Hint 1
> `@click`で指定された関数の第1引数には[[MouseEvent (JavaScript)|MouseEvent]]が渡されます。
> [!hint]- Hint 2
> ボタンの文字列は[[Event.target (JavaScript)|Event.target]]の中に含まれています。[[Chrome devtools]]のコンソールで調べてみるのもいいですね。
> [!hint]- Hint 3
> [[Event.target (JavaScript)|Event.target]]の結果は[[console.log]]では出力できません。[[console.dir]]を使いましょう。
> [!hint]- Hint 4
> 普通に実装すると型エラーになるので回避策が必要です。たとえば...
> ```ts
> const handleClick = (event: MouseEvent) => {
> const buttonElement = event.target as HTMLButtonElement;
> }
> ```
## References
[イベントハンドリング \| Vue\.js](https://v3.ja.vuejs.org/guide/events.html#%E3%82%A4%E3%83%98%E3%82%99%E3%83%B3%E3%83%88%E3%81%AE%E8%B3%BC%E8%AA%AD)