これはなに
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
に反映される。