概要
Vue3.4からめでたく安定版となったdefineModel()、こんな形で簡単に双方向バインディングができるようになりました
// 親から v-model 経由で使用される、"modelValue" props を宣言する
const model = defineModel<String>()
// 変更された時に "update:modelValue" イベントを発行
model.value = 'hello'
これまで双方向バインディングをするためのv-model
Propを定義するためにはProps
とEmits
両方を定義して更新タイミングでemit
を呼ぶというめんどくさい構造だったのでとても嬉しい変更です
そんな便利defineModel
ですが実はオブジェクトで使用してしまうとプロパティ変更で検知してくれないのでちょっと工夫が必要だったりします(めんどい)
const model = defineModel<Model>()
model.name = "nanika" // 親にupdateが走らない
解決法
こうすればおkです
const model = defineModel<Model>()
watch(
model,
(newVal) => {
model.value = { ...newVal }
},
{ deep: true }
)
model.name = "nanika" // 親に伝わる!
仕組みとしてはdeep watchでプロパティ変更検知したら再度model
の方に代入することで変更を伝えています
参考文献
-
https://github.com/orgs/vuejs/discussions/10538
- これに関した議論があったようです