VueのdefineModelを活用した入力コンポーネントの作成方法【Vue3.4】

目次
はじめに
2023年12月29日、Vue.js 3.4がリリースとなりました🎉
3.4で追加された機能は以下のブログで確認できます。
この記事ではVue.js 3.4の中で特に便利だと感じたdefineModelについて、実例を交えながら使い方を解説します。
defineModelを使った入力コンポーネントの作成
inputを含むコンポーネントを作成する場合、今までは引数を定義するためのpropsと、親コンポーネントへ値を受け渡す関数を定義するためのemits、どちらも記述する必要がありました。
defineModelを使うとpropsとemitsを記述することなく、入力コンポーネントを実現することができます。
例として、今回は以下のようなコンポーネントを作成してみます。

今回作成するコンポーネント
インプット部分が子コンポーネントとなっており、子コンポーネントのインプットに入力された内容を親コンポーネントに表示しています。
このコンポーネントを従来の記法とdefineModelを活用した記法で作成してみます。
従来の記法
App.vue
<script setup>
import Child from "./Child.vue";
import { ref } from "vue";
const msg = ref("Hello World!");
</script>
<template>
<h1>{{ msg }}</h1>
<Child v-model="msg" />
</template>
Child.vue
<script setup>
const props = defineProps(["modelValue"]);
const emit = defineEmits(["update:modelValue"]);
</script>
<template>
<input :value="props.modelValue" @input="(e) => emit('update:modelValue', e.target.value)" />
</template>
子コンポーネント内でpropsを定義することで親コンポーネントから値を受け取り、emitsを定義することで親コンポーネントへ値を送れるようにしています。
また、propsで定義した値は書き込みが出来ないため、v-modelに設定することができません。
代わりに、:valueにpropsを設定することによって値を表示、@inputに入力時の処理を書いています。
defineModelを活用した記法
App.vueは上記と同じです。
Child.vue
<script setup>
const model = defineModel();
</script>
<template>
<input v-model="model" />
</template>
propsとemitsを記述する代わりに、defineModelを記述することで変数の受け取りと変更ができるようになります。
また、v-modelの値は変更可能なので、そのままinputタグのv-modelにdefineModelで定義した変数を渡すことができます。
上記のコードは、以下のプレイグラウンドで動作させることができます。
複数のv-modelを渡す方法
複数のv-modelを使用する場合は、v-model引数を用いてv-model:変数名と記述します。
子コンポーネントではdefineModelに引数を与えてdefineModel('変数名')と記述します。
以下に例を示します。
App.vue
<script setup>
import { ref } from "vue";
import UserName from "./UserName.vue";
const first = ref("John");
const last = ref("Doe");
</script>
<template>
<h1>{{ first }} {{ last }}</h1>
<UserName v-model:first-name="first" v-model:last-name="last" />
</template>
UserName.vue
<script setup>
const firstName = defineModel("firstName");
const lastName = defineModel("lastName");
</script>
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
</template>
上記のコードは、以下のプレイグラウンドで動作させることができます。
TypeScriptでの使用
defineModelは型引数を取ることができます。
<script setup lang="ts">
const model = defineModel<string>();
</script>
型引数を記述することによって、defineModelが受け入れられる型を制限することができます。
まとめ
この記事ではVue.js 3.4の中で特に便利だと感じたdefineModelについて、実例を交えながら使い方を解説しました。defineModelを使うと入力コンポーネントを少ないコード量で書くことができるので、ぜひ使ってみてください。
参考
- Announcing Vue 3.4
- Component v-model
- defineModel
関連記事

AWS IAMでPasskeyが利用可能に Windows PCで指紋認証を設定してみました

React公式チュートリアルをVueでも書いて比較してみた

Vueのスコープ付きCSSで子コンポーネントにCSSを適用する【Vue3】

Vercel(Hobby)→AWS Amplify 移行して分かった両者の違い

手軽に使えるVueプレイグラウンド環境。Vue SFC Playground解説

Vite、TailwindCSS v4環境を構築【Tailwind CSS v4-alpha】
オススメ記事

React公式チュートリアルをVueでも書いて比較してみた

フロントエンド開発体験を向上させる10のnpmライブラリ【2024年版】

Nuxt3にStorybookを導入する方法

NuxtJSを使ってブログを作ってみた【Nuxt Content/TailwindCSS/daisyUI】

