Vue3 + Typescriptでselect boxコンポーネントを作ってみる

プログラミング

業務でVue3に触りそうなので勉強

form関連のコンポーネントを作成することは共通して多いと思うので

selectboxのコンポーネントを作成してみる

BasicSelect.vue

今回作成したselect box用のコンポーネント

細かくは後述

<script setup lang="ts">
import { defineProps } from 'vue'

const props = defineProps({
  options: Object
})

const emit = defineEmits(['update:modelValue'])
</script>

<template>
  <select
    @change="
      $event.target && emit('update:modelValue', ($event.target as HTMLSelectElement).value)
    "
  >
    <option
      v-for="(option) in props.options"
      :key="option.value"
      :value="option.value"
    >
      {{ option.label }}
    </option>
  </select>
</template>

<style lang="scss" scoped>
</style>

細かく見ていく

defineProps

const props = defineProps({
  options: Object
})

propsは親コンポーネントから子コンポーネントに値を受け渡すもの

ここでは親コンポーネントからselectで使用する選択肢を受け取るpropsを定義

defineEmits

const emit = defineEmits(['update:modelValue'])

emitは子コンポーネントから親コンポーネントへイベントを通知するもの

親コンポーネントから受け取ったv-modelをupdateするemitを定義する

select boxが変更されたとき

  <select
    @change="
      $event.target && emit('update:modelValue', ($event.target as HTMLSelectElement).value)
    "
  >

select boxが変更された際にemitで定義したupdate:modelvalueを呼び出し、引数にselect boxのvalueを渡してあげる

$event.targetはイベントが発生した要素、つまりユーザーが操作したHTML要素を参照

as HTMLSelectElementはTypeScriptの型アサーション(型変換)を使用し、

$event.targetがHTMLSelectElement(HTMLのselect要素)であること指定してvalueを取得

親コンポーネントからの呼び出し

親コンポーネントからは以下のようにBasicSelectコンポーネントを呼び出せる

<script setup lang="ts">
    import { ref } from "vue";
    import BasicSelect from "../components/form/BasicSelect.vue";

    const selectedItem = ref<string>("1");

    const options: { label: string; value: string }[] = [
        {
                label: "選択肢1",
                value: "1"
        },
        {
                label: "選択肢2",
                value: "2"
        },
        {
                label: "選択肢3",
                value: "3"
        }
    ];
</script>

<template>
  <BasicSelect :options="options" v-model="selectedItem" />

  <p>現在選択中: {{ selectedItem }}</p>
</template>

<style scoped>
</style>

画面を確認するとこんな感じ

selectboxで選択変えて下の現在選択中も連動して変わっているので大丈夫そう

以上