Subscribe on changes!

defineModel's default value is non-reactive

avatar
Jan 5th 2024

Vue version

3.4.5

Link to minimal reproduction

https://play.vuejs.org/#eNqNUsluGzEM/RVBl7RAZoTC7cWYGOmSQwt0QVv0pIsyQ9tytUGiHAPu/Hs5cjyZOAtyE8lH8vE97fn7EOptBj7nTWqjDsgSYA7MKLe6kByT5AvpWu8SsqWP9pNCxS5YB0vt4KvvwDR76Rjz15s/ymSYs4RRuxX7x1w2Rrp+8aoAqENlg3NWomnD2dmQ6Qn6WrpGHGjQUgoQbDAKgSLGmvWbxX4/sqiPE1jfN4JqBaNdyMi2lR2o0QEP0JIzQdBGTGbzc65t8BErq0K9Sd6RHoWnvC2QDCNzyUmwIZZ8jRjSXIi2c9RGG/U21g5QuGDFJcFEzA61harz9nJWv63fiU4nnKZrSLa6jv4mQaQhkp9P1ghKbiFWEVwHEeJL1560TVeflB6sP5pBomAi45d6dSJJ623QBuL3gJo+xj1plDH+5kvJYcww3tKuof37SH6TdoebfkQozCb3o4orwEP56tc32NF7LJLB2dza8ETxJyRv8sDxAPuQXUe0J7jC9nNxmP7s73S1Q3DpeNRAtKhR8MWPj8+cfkd3Vs9GFfv/0tolQw==

Steps to reproduce

Set up a standard defineModel with a default value that's an object. The object contains a string (for example). We simply link this value to the v-model of an input element. We also show the value of it in the template.

What is expected?

When you type something in the input element, it should show the updated value.

What is actually happening?

You can type in the input element, but the value isn't updated in real-time, only after a forced update.

System Info

No response

Any additional comments?

No response

avatar
Jan 5th 2024

defineModel's defaulrt valuze behaves just like a normal prop's default value, because that's what it's used for: setting the default value of the modelValue prop (unless another name was defined for the model).

So this is expected behavior. if you want a reactive object, create one in the usual way.

avatar
Jan 5th 2024

@LinusBorg So, I've tried some things based on what you're suggesting. The most logical one was encapsulating the object in a ref function call.

const formData = defineModel<{ objValue: string }>({ default: ref({ objValue: string }) })

This seems to be the most straight forward solution but the problem here is that it first renders the component before the default value is applied. Which means a lot of 'Cannot read properties of undefined' errors and obviously I'm not going to apply optional chaining to every value (formValue?.objValue) when I expect them to be defined anyway.

I also tried defining the reactive variable by itself and then passing it to the defineModel, but the defineModel is called before the variable is instantiated, so that's not an option.

Maybe I misunderstood you?

avatar
Jan 5th 2024

ref() reactive()

also, props defaults that return options need to be defined as a factory function, as explained in the docs.

default: () => reactive({ objectValue })

If you have more usage questions, please use our Discord chat or the Dicsussions section of this repo.