[[📗14 帰ってきたイベントハンドリング]] < [[📒Vue.jsクエスト]] > [[📗16 リポジトリ検索の死闘]] ## Abstract この先は中ボスですが、その前に[[inputタグ]]のスマートな実装方法を学びましょう。 ## Lesson [[v-model]]ディレクティブを使うと、[[inputタグ]]の実装をよりシンプルに書けます。 たとえば以下のコードは ```html <script setup lang="ts"> import { ref } from "vue"; const text = ref(""); const handleInput = (e: Event) => { text.value = (e.target as any).value; }; </script> <template> <div> <span>{{ text }}</span> <button @click="text = ''">クリア</button> </div> <input :value="text" @input="handleInput" /> </template> ``` 以下のようになります。 ```html <script setup lang="ts"> import { ref } from "vue"; const text = ref(""); </script> <template> <div> <span>{{ text }}</span> <button @click="text = ''">クリア</button> </div> <input v-model="text" /> </template> ``` ## Missions ### Mission 1 #😁EASY 以下のコードが期待通り動作するよう書き換えてください。 ```html <script setup lang="ts"> import { ref } from "vue"; const checked = ref(false); </script> <template> <div>check: {{ checked }}</div> <input type="checkbox" :v-model="checked" /> </template> ``` %% 回答例 ```html <script setup lang="ts"> import { ref } from "vue"; const checked = ref(false); </script> <template> <div>check: {{ checked }}</div> <input type="checkbox" v-model="checked" /> </template> ``` %% ### Mission 2 #🙂NORMAL 以下破線内のようなUIのコードを書いてください。ただし、『選択した文字列がここに表示される』は固定文言ではなく、選択された項目の文字列が表示されるものとします。 <div style="padding: 15px; border: dotted 1px"> <div>選択した文字列がここに表示される</div> <select> <option>タツヲ</option> <option>みみぞう</option> <option>マサハル</option> </select> </div> %% 回答例 ```html <script setup lang="ts"> import { ref } from "vue"; const selected = ref("タツヲ"); </script> <template> <div>{{ selected }}</div> <select v-model="selected"> <option>タツヲ</option> <option>みみぞう</option> <option>マサハル</option> </select> </template> ``` %% ### Mission 3 #🙂NORMAL 以下のコードについて、入力欄が変わった時ではなく、入力欄からフォーカスが外れた時に表示を変更するよう、コードを修正してください。 ```html <script setup lang="ts"> import { ref } from "vue"; const text = ref(""); </script> <template> <div>{{ text }}</div> <input type="text" v-model="text" /> </template> ``` %% 回答例 ```html <script setup lang="ts"> import { ref } from "vue"; const text = ref(""); </script> <template> <div>{{ text }}</div> <input type="text" v-model.lazy="text" /> </template> ``` %% > [!hint]- Hint 1 > https://vuejs.org/guide/essentials/forms.html#lazy ### Mission 4 #😵HARD 以下破線内のようなUIのコードを書いてください。ただし、『選択したキャラの画像が表示される』は固定文言でなく、選択された項目に紐づく画像が表示されるものとします。 <div style="padding: 15px; border: dotted 1px"> <div>選択したキャラの画像が表示される</div> <select> <option>タツヲ</option> <option>みみぞう</option> <option>マサハル</option> </select> </div> 選択肢と画像URLのマッピングは以下。 | 選択肢 | 画像URL | | -------- | ---------------------------------------------------------------------------------------------------------------------------- | | タツヲ | https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/tatsuwo.jpg | | みみぞう | https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/Pasted%20image%2020210605212644.png | | マサハル | https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/masaharu.jpg | > [!hint]- Hint 1 > https://vuejs.org/guide/essentials/forms.html#value-bindings %% 回答例 [[v-for]]を使えれば及第点。 ```html <script setup lang="ts"> import { ref } from "vue"; const values = [ { name: "タツヲ", url: "https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/tatsuwo.jpg", }, { name: "みみぞう", url: "https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/Pasted%20image%2020210605212644.png", }, { name: "マサハル", url: "https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/masaharu.jpg", }, ]; const selected = ref(values[0]); </script> <template> <img :src="selected.url" style="height: 480px; display: block" /> <select v-model="selected"> <option v-for="v in values" :value="v">{{ v.name }}</option> </select> </template> ``` %% ## References - [Form Input Bindings \| Vue\.js](https://vuejs.org/guide/essentials/forms.html)