✌️

VueのdefineModelの使い方

2024/03/29に公開

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