これはなに

Vue 3.4以降で、カスタムコンポーネントでv-modelを双方向バインディングして使えるようにする方法のメモ。
方法

Vue 3.4以前の場合は、propsとemitを使って、v-modelの双方向バインディングを行っていた。
Vue 3.4以前の方法
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input
:value="props.modelValue"
@input="emit('update:modelValue', $event.target.value)"
/>
</template>しかし、Vue 3.4からはdefineModel()を使うことで、より簡単に双方向バインディングできる。
例を以下にあげる。以下の例はテキスト入力コンポーネントである。
InputText.vue
<template>
<input
:id="id"
v-model="model"
type="text"
:placeholder="placeholder"
/>
</template>
<script lang="ts" setup>
const model = defineModel<string>();
interface Props {
id: string;
placeholder: string;
}
withDefaults(defineProps<Props>(), {});
</script>const model = defineModel<string>();で作成したmodelを、v-modelにバインドする。
このコンポーネントを使うときは、次のようにする。
index.vue
<template>
<InputText
id="search"
v-model="searchQuery"
:placeholder="入力してください"
/>
</template>
<script lang="ts" setup>
const searchQuery = ref('');
</script>v-modelにsearchQueryをバインドすることで、InputTextコンポーネントで入力した値がsearchQueryに反映される。
