
・Vue.jsのdefineModelの使い方は?
こんな疑問にお答えします。
defineModelはVueの子コンポーネントで、v-modelを簡単に定義するしくみみたいなもの。
子コンポーネントのv-modelのデータ内容を、親に共有できるのが特徴です。

かなり便利だよ!

ということで、この記事では「defineModelの使い方」について解説していきます!
・Vue.jsのdefineModelの基本的な使い方
・Vue.jsのdefineModelのその他の使い方


目次
【解説】Vue.jsのdefineModelの使い方【v-modelを共有】
そんなdefineModelを使った例となるコードがこちら↓
<script setup lang="ts">
import { ref } from 'vue';
import Child from './components/Child.vue';
const message = ref('おはようございます');
</script>
<template>
<p>親:{{ message }}</p>
<Child v-model="message"/>
</template>
<script setup lang="ts">
const model = defineModel();
</script>
<template>
<p>子:{{ model }}</p>
<input type="text" v-model="model">
</template>
これで子のv-modelの内容を、親に共有することができます!
コードの中で重要な点がこちら↓
①親:コンポーネントタグにv−modelを記述
②子:defineModelを使う
順に解説してきます。
まず親側で、読み込むコンポーネントタグに「v-model」を記述します。
その値にリアクティブな変数名を入れましょう。
<Child v-model="変数名"/>
今回は下記のようにしてみました↓
<script setup lang="ts">
import { ref } from 'vue';
import Child from './components/Child.vue';
const message = ref('おはようございます');
</script>
<template>
<Child v-model="message"/>
</template>

続いて子側で「defineModel」を呼び出して使います。
const 変数名 = defineModel();
その返り値(refオブジェクトの感じ)を利用します。
今回は例として下記コードのように記述↓
<script setup lang="ts">
const model = defineModel();
</script>
<template>
<p>子:{{ model }}</p>
<input type="text" v-model="model">
</template>
これで下記例だと親の「message」と子の「model」が同期されるようになりました。
<script setup lang="ts">
~~
const message = ref('おはようございます');
</script>
<template>
<Child v-model="message"/>
</template>
<script setup lang="ts">
const model = defineModel();
</script>
<template>
<p>子:{{ model }}</p>
<input type="text" v-model="model">
</template>
これだけでv-modelの内容を、親に共有することができます!
【解説】Vue.jsのdefineModelの使い方【その他】
最後に「defineModel」のその他の知識について解説していきます。
・使いすぎは注意
・引数で設定可能
・複数v-modelを使う場合
順に見ていきましょう。
「defineModel」はかなり便利ですが、使いすぎは注意とのこと。
というのも使いすぎると、親子間での流れがわかりにくくなるからですね。
基本的には「props」や「emit」を使っておき、v-modelのデータを共有したいときだけ利用すべし。


ちなみに「defineModel」は引数にオブジェクトがとれ、その中で色々設定ができます。
<script setup lang="ts">
const model = defineModel({
type: String,
default: 'こんにちは',
});
</script>
型やデフォルトの値などが設定可能です。
実は複数のv-modelをdefineModelで指定することができます。
やり方としては下記↓
- 親:「v-model:識別子」をつける
- 子:「defineModel」をその数文作る
- 子:「defineModel」の引数に識別子をつける
<script setup lang="ts">
import { ref } from 'vue';
import Child from './components/Child.vue';
const message = ref('おはようございます');
const name = ref('田中さん');
</script>
<template>
<p>親:{{ message }}</p>
<Child v-model:item-message="message" v-model:item-name="name"/>
</template>
<script setup lang="ts">
const model = defineModel('itemMessage');
const model02 = defineModel('itemName');
// 第二引数で設定も可能です
// const model02 = defineModel('itemName', {
// type: String,
// default: '山田さん',
// });
</script>
<template>
<p>メッセージ:{{ model }}</p>
<input type="text" v-model="model">
<p>名前:{{ model02 }}</p>
<input type="text" v-model="model02">
</template>

ちなみにv-model最初の一個目だけは識別子なしでも使えるよ


【解説】Vue.jsのdefineModelの使い方【v-modelを共有】:まとめ
- 子のv-modelのデータ内容を親に共有できるのが特徴
- 親側でコンポーネントタグにv−modelを記述
- 子側で「defineModel」を呼び出して使う
- 引数で設定可能
- 複数使う場合は識別子を使う

Vue.jsのdefineModelを使う時はためしてみてね!