VueのdefineModelを活用した入力コンポーネントの作成方法【Vue3.4】
![サムネイル](https://d2s4ypph6g1t06.cloudfront.net/img/pc/programming_vue-define-model_vue.avif)
目次
はじめに
2023年12月29日、Vue.js 3.4がリリースとなりました🎉
3.4で追加された機能は以下のブログで確認できます。
この記事ではVue.js 3.4の中で特に便利だと感じたdefineModel
について、実例を交えながら使い方を解説します。
defineModelを使った入力コンポーネントの作成
input
を含むコンポーネントを作成する場合、今までは引数を定義するためのprops
と、親コンポーネントへ値を受け渡す関数を定義するためのemits
、どちらも記述する必要がありました。
defineModel
を使うとprops
とemits
を記述することなく、入力コンポーネントを実現することができます。
例として、今回は以下のようなコンポーネントを作成してみます。
![今回作成するコンポーネント](https://d2s4ypph6g1t06.cloudfront.net/img/pc/programming_vue-define-model_define-model.avif)
今回作成するコンポーネント
インプット部分が子コンポーネントとなっており、子コンポーネントのインプットに入力された内容を親コンポーネントに表示しています。
このコンポーネントを従来の記法と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