はじめに
前回の記事でvueの基本的な仕組みのpropsとemitについて記事を書きましたが、Vue3.4からdefineModelが使えるようになり親子の双方向バインディングがわかりやすくなったみたいなので学習していこうと思います。
今回はprops、emitを使用した方法とdefineModelを使用した方法で簡単なカウントアプリを作成してみたいと思います。
親画面であるCountView.vueは同様のものを使います。
CountView.vue
<script setup>
import { ref } from 'vue'
import Count from '../components/CountComponent.vue'
// リアクティブ変数
const countValue = ref(0)
</script>
<template>
<div>
<Count v-model="countValue" />
<p>View Count: {{ countValue }}</p>
</div>
</template>
CountComponent.vue
// 従来の書き方
<script setup>
import { ref } from 'vue';
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: {
type: Number,
default: 0
}
});
const emit = defineEmits(['update:modelValue']);
const count = ref(props.modelValue);
const increment = () => {
count.value++;
emit('update:modelValue', count.value);
};
const decrement = () => {
count.value--;
emit('update:modelValue', count.value);
};
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
こちらが従来の書き方でした。
親画面からmodelValue(v-model)を受け取ってボタンがクリックされたらemit('update:modelValue')で親画面に返し画面に描画する仕組みでした。
しかし、defineModelの登場により、この冗長なコードを省略できるようになったみたいなので試してみます。
CountComponent.vue
// defineModel を使用
<script setup>
const count = defineModel()
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
めちゃくちゃシンプルになりましたね!
まとめ
-
defineModelはmodelValueプロパティとupdate:modelValueイベントを自動的に管理してくれる -
defineModelを使用することで、コードが簡潔になり、v-modelとの連携がスムーズになる
どんどん新しくなっているため引き続きキャッチアップを続けて取り残されないようにしていきたいと思います!