✌️
VueのdefineModelの使い方
Vue3 の defineModel 便利ですよね!
使い方を見ていきましょう!
基本的な使い方
子コンポーネントで defineModel を使うことで、簡単に双方向バインディングを書くことができます。
今までは defineProps と defineEmits に定義しなければならなかったのが、1 つにまとまって書きやすくなりました。素敵ですね!
下記に親子コンポーネントで v-model で値のやりとりをし、子コンポーネントのボタンをクリックすることで値が増える例を示します。
Child.vue
<script setup lang="ts">
const model = defineModel<number>();
const onClick = () =>
(model.value = model.value === undefined ? 0 : model.value * 2);
</script>
<template>
<p>v-model: {{ model }}</p>
<button @click="onClick">ボタン</button>
</template>
Parent.vue
<script setup lang="ts">
import { ref } from "vue";
import Child from "./Child.vue";
const countModel = ref(1);
</script>
<template>
<Child v-model="countModel" />
</template>
defineModel に getter、setter の登録
今まで v-model で親からやってきた値を少し変形して画面に表示したい場合等は、computed を使用して関数を定義しないといけませんでした。
しかし、defineModel を使用すれば一緒に記述できて便利です。
Child.vue
<script setup lang="ts">
const model = defineModel<number>({
get: (value: number) => {
return -value;
},
set: (value: number) => {
console.log(value);
return value;
},
});
const onClick = () =>
(model.value = model.value === undefined ? 0 : model.value * 2);
</script>
<template>
<p>v-model: {{ model }}</p>
<button @click="onClick">ボタン</button>
</template>
v-model を複数登録できるようにする
defineModel の第一引数に文字列を渡すことで、v-model に名前をつけることができます。
これによって v-model を複数設定できます。
Child.vue
<script setup lang="ts">
const model = defineModel<number>("count", {
get: (value: number) => {
return -value;
},
set: (value: number) => {
console.log(value);
return value;
},
});
const onClick = () =>
(model.value = model.value === undefined ? 0 : model.value * 2);
</script>
<template>
<p>v-model: {{ model }}</p>
<button @click="onClick">ボタン</button>
</template>
Parent.vue
<script setup lang="ts">
import { ref } from "vue";
import Child from "./Child.vue";
const countModel = ref(1);
</script>
<template>
<Child v-model:count="countModel" />
</template>
Discussion