[[📗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)