0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Vue3】genericを使用した型安全なラジオボタンコントロール

Posted at

完成イメージ

image.png

コンポーネント

RadioButton.vue
<template>
  <div class="border rounded border-success-subtle">
    <div v-for="item in items" :key="item.id">
      <input
        type="radio"
        :id="item.id"
        :name="props.name"
        :value="item.value"
        v-model="modelValue"
        :required="props.required"
      />
      <label :for="item.id">{{ item.labelName }}</label>
    </div>
  </div>
</template>

<script setup lang="ts" generic="T extends string | boolean | undefined">
export interface InputRadioItem<T> {
  id: string;
  labelName: string;
  value: T;
}

const props = defineProps<{
  modelValue: T;
  name: string;
  items: InputRadioItem<T>[];
  required?: boolean;
}>();

interface Emits {
  (e: "update:modelValue", value: T): void;
}
const emits = defineEmits<Emits>();

const modelValue = computed({
  get: () => props.modelValue,
  set: (value) => {
    emits("update:modelValue", value);
  },
});
</script>

  • generic="T"を定義する
  • 許容したい型をextendsに定義する

使用側

index.vue
<template>
   <form>
       <RadioButton :items="listItems" v-model="selectedValue" name="fruitsRadio" />
       selected: {{ selectedValue }}
   </form>
</template>

<script setup lang="ts">
import type { InputRadioItem } from "~/components/RadioButton.vue";
const radioItems: InputRadioItem<string>[] = [
  { id: "apple", labelName: "りんご", value: "apple" },
  { id: "banana", labelName: "バナナ", value: "banana" },
  { id: "oranage", labelName: "みかん", value: "oranage" },
];

const selectedValue = ref(undefined);
</script>
  • InputRadioItemでvalueに使用したい型を指定することで、modelValueの型と連動する
  • valueとselectedValueが異なるとコンパイルエラーが出る
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?