[[📗13 リストの取り扱い]] < [[📒Vue.jsクエスト]] > [[📗15 Form Inputとv-model]] ## Abstract そろそろ強敵の気配を感じてきましたが... このタイミングでイベントハンドリングの再来です。[[📗04 アットマークは耳マーク]]で学んだ知識を活かしたうえで臨みましょう。 ## Lesson ### 2種類のハンドラー 実行したい文を指定するハンドラーを[[インラインハンドラー]]といいます。 ```html <!-- クリックすると変数countの値がインクリメントされる --> <button @click="count++">カウントアップ</button> ``` 実行したいメソッドを指定するハンドラーを[[メソッドハンドラー]]といいます。 ```html <!-- クリックするとmethodメソッドが呼び出される --> <button @click="method">カウントアップ</button> ``` ### [[イベント修飾子]] `@click.stop`や`@click.stop.prevent`のように、イベントに対して[[イベント修飾子]]をつけることができます。 たとえば、以下2つのコードは等価です。 ```html <template> <input id="test" type="checkbox" @click.prevent /> <label for="test">クリックしてもチェックできない</label> </template> ``` ```html <template> <input id="test" type="checkbox" @click="(e) => e.preventDefault()" /> <label for="test">クリックしてもチェックできない</label> </template> ``` ### キーの押下判定 [[@keyup]]のあとに様々な[[キー修飾子]]を指定できます。以下は`Enter`を押したときに`handleEnter`メソッドを呼び出すコードです。 ```html <script setup lang="ts"> const handleEnter = () => { console.log("handleEnter"); }; </script> <template> <input type="text" @keyup.enter="handleEnter" /> </template> ``` ## Missions ### Mission 1 #🙂NORMAL 以下2つのコードにおける**挙動の違い**を説明してください。 ```html <template> <button @click="handleClick">click</button> </template> ``` ```html <template> <button @click="handleClick()">click</button> </template> ``` %% 回答例 上は`handleClick`の第1引数にイベント引数が渡ってくるが、下は渡ってこない。 %% ### Mission 2 #🙂NORMAL 以下のコードには『innerエリアをクリックしたときも`clickouter`が実行されてしまう』という不具合があります。**不具合の理由を説明**し、**コードを修正**してください。 ```html <script setup lang="ts"> const clickOuter = () => { console.log("clickOuter"); }; const clickInner = () => { console.log("clickInner"); }; </script> <template> <div class="outer" @click="clickOuter"> <div class="inner" @click="clickInner"></div> </div> </template> <style scoped> .outer { width: 200px; height: 200px; background-color: red; } .inner { width: 100px; height: 100px; background-color: blue; } </style> ``` > [!hint]- Hint 1 > https://vuejs.org/guide/essentials/event-handling.html#event-modifiers %% 回答例 クリックイベントが親まで伝播してしまうため。 ```html <script setup lang="ts"> const clickOuter = () => { console.log("clickOuter"); }; const clickInner = () => { console.log("clickInner"); }; </script> <template> <div class="outer" @click="clickOuter"> <div class="inner" @click.stop="clickInner"></div> </div> </template> <style scoped> .outer { width: 200px; height: 200px; background-color: red; } .inner { width: 100px; height: 100px; background-color: blue; } </style> ``` %% ### Mission 3 #😵HARD 以下のコードには不具合があります。**不具合およびその理由**を説明し、**コードを修正**してください。 ```html <script setup lang="ts"> import { ref } from "vue"; const text = ref(""); const handleChange = (e: any) => { text.value = e.target.value; }; </script> <template> <div>{{ text }}</div> <form> <input type="text" @input="handleChange" /> </form> </template> ``` > [!hint]- Hint 1 > [[formタグ]]は特定条件下でEnterを押すと`submit`イベントが着火します。 > [!hint]- Hint 2 > [[Event.preventDefault (JavaScript)|Event.preventDefault]]を使うと規定のイベントをキャンセルできます。通常の開発では。 %% 回答例 入力欄でEnterを押すと画面がリロードされてしまう。これはformのsubmitイベントによる規定アクションであるから。 ```html <script setup lang="ts"> import { ref } from "vue"; const text = ref(""); const handleChange = (e: any) => { text.value = e.target.value; }; </script> <template> <div>{{ text }}</div> <form @submit.prevent> <input type="text" @input="handleChange" /> </form> </template> ``` %% ### Mission 4 #😵HARD `Ctrl`**のみ**を押しながらマウスの右クリックを押したときだけ、クリックされた要素の縦と横が2倍に増えるコードを書いてください。 > [!hint]- Hint 1 > 処理については [[📗11 Vueらしくスタイルをはめる]] の知識を使います。 > [!hint]- Hint 2 > `Ctrl`以外のキーが押されている場合は動作しないよう、とある[[キー修飾子]]を使う必要があります。 > [!hint]- Hint 3 > https://vuejs.org/guide/essentials/event-handling.html#key-modifiers %% 回答例 ```html <script setup lang="ts"> import { ref } from "vue"; const width = ref(50); const height = ref(50); const handleRightClick = () => { width.value *= 2; height.value *= 2; }; </script> <template> <div :style="{ width: `${width}px`, height: `${height}px` }" style="background-color: blue" @click.right.ctrl.exact="handleRightClick" ></div> </template> ``` %% ## References - [Event Handling \| Vue\.js](https://vuejs.org/guide/essentials/event-handling.html)