(Vue 3.2)ツンデレな妹に説明されるpropsとemitsを使ったUIコンポーネントの作り方
もう、本当にバカ兄貴ね…。仕方ないわ、Vueで実装するって観点から、以下の4つのパターンを教えてあげるから、ちゃんと覚えておきなさいよね。
- テキストインプット
- トグルボタン
- セレクト
- ラジオボタン
これらの実装方法がわかったら、他のUIコンポーネントだってアンタみたいなバカ兄貴でも定義できるかもしれないわね。
Vue公式の説明はこれなんだけどアンタには難しいかもしれないから、私が丁寧に説明してあげるわ。感謝しなさい!
テキストインプット
今回紹介するUIの中では一番ベーシックなものだけど、アンタにはちょうどいいかもね。テキストを入力するだけのシンプルなUIコンポーネントよ。
呼び出し
<TextInput v-model="textRef" />
定義
<script setup>
defineProps({ modelValue: String })
defineEmits(['update:modelValue'])
</script>
<template>
<div>
<input
type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</div>
</template>
<!-- スタイルはお好みで -->
トグルボタン
リアクティブでtrueやfalseの真偽値を扱う場合に使うんだけど、アンタにはちょっと難しいかな。スイッチのようにオンとオフを切り替えられるUIコンポーネントなのよ。
呼び出し
<ToggleButton v-model="boolRef" />
定義
<script setup>
defineProps({ modelValue: Boolean })
defineEmits(['update:modelValue'])
</script>
<template>
<label :class="{ active: modelValue }">
<span class="inner-circle"></span>
<input
type="checkbox"
@input="$emit('update:modelValue',!modelValue)"
/>
</label>
</template>
<!-- スタイルはお好みで -->
セレクト
複数の選択肢から一つを選ぶことができるUIコンポーネントね。v-modelの値が数値型でも文字型でも対応できるように工夫してあるんだけど、アンタにもわかるかしら?
呼び出し
<!--
const options = [
{ value: 'subaru', label: 'スバル' },
{ value: 'mitsubishi', label: '三菱' },
{ value: 'honda', label: 'ホンダ' },
]
const selectedOption = ref(options[0].value)
-->
<SelectOption v-model="selectedOption" :options="options" />
定義
<script setup>
defineProps({ modelValue: String | Number, options: Array })
defineEmits(['update:modelValue'])
</script>
<template>
<div>
<select @input="$emit('update:modelValue', $event.target.value)">
<option v-for="opt in options" :value="opt.value">
{{ opt.label }}
</option>
</select>
</div>
</template>
<!-- スタイルはお好みで -->
ラジオボタン
これは、複数の選択肢から一つだけ選ぶことができるUIコンポーネントよ。v-modelの値はpropsでバケツリレーできない仕様があるんだけど、その問題を解決してるのがポイントだから、ちゃんと覚えておきなさいね。checked属性をうまく使うの。
呼び出し
<RadioButton v-model="radioRef" value="japan" label="日本" />
<RadioButton v-model="radioRef" value="korea" label="韓国" />
<RadioButton v-model="radioRef" value="usa" label="アメリカ" />
定義
<script setup>
defineProps({ modelValue: String, value: String, label: String })
defineEmits(['update:modelValue'])
</script>
<template>
<label>
<input
type="radio"
:checked="modelValue === value"
@input="$emit('update:modelValue', value)"
/>
<span>{{ label }}</span>
</label>
</template>
<!-- スタイルはお好みで -->
まとめ
ふん、本当にアンタって困ったバカ兄貴ね。でもまぁ、せっかくだから、これでアンタもVueでカスタムUIコンポーネントが作れるようになって欲しいわ。だから、しっかり練習して、少しでも役に立つ兄貴になりなさい!
この記事で紹介した4つのパターンをマスターして、VueプロジェクトでのUIコンポーネント実装に自信を持って取り組むことね。もしかしたら、アンタが成長することで、私もちょっぴり誇りに思うかもしれないわ。だから、これからもVueの世界を楽しみながら学んでいってほしいのよ。それじゃあ、がんばってね、バカ兄貴!
Discussion