Subscribe on changes!

Vue 3 v-model binding not working when passing filtered data object

avatar
Mar 2nd 2023

Vue version

3.2.47

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-turhke?file=package.json

Steps to reproduce

The minimal project on stackblitz illustrates the problem.

I have defined two child components to edit a user:

  • One attempts to edit the user by passing the object in the v-model (v-model:user="users[index]")
  • The other edits the user by passing the properties of the object directly (v-model:first-name="users[index].firstName" + v-model:first-name="users[index].lastName"

Both implementation work well when passing directly users[index] in the v-model binding (v-model:user="users[index]"). But when binding my child component using an object that is the result of a computed property (v-model:user="filteredUsers[index]") the two-way binding doesn't work in the first case, only in the second case.

I guess this has to do with the fact that the filter method does a shallow copy of the object. But why does it work when binding directly the properties of the object and not when binding the object? in both case the users array is filtered.

Note: I'm using the multiple v-model binding syntax coming from Vue 3 (v-model:myObject="myObject").

What is expected?

I would expect that v-model binding works with the computed property.

What is actually happening?

The users array is not updated in the parent when binding using the computed property (v-model:user="filteredUsers[index]"), only when binding the users array directly (v-model:user="users[index]")

System Info

Nothing particular, see project config on stackblitz

Any additional comments?

I would expect same behaviour when binding the object or the properties of the object:

  • Object binding doesn't work
    • v-model:user=filteredUsers[index] doesn't work
  • Properties binding work
    • v-model:first-name=filteredUsers[index].firstName
    • v-model:last-name=filteredUsers[index].lastName
avatar
Mar 2nd 2023

This behavior is expected. UserBindingObject.vue emits a new, cloned user object. Which will replace the orginal user object.

But in the case of the filtered computed, it will replace the user object in the filtered array that was returned by the computed property. The original array will still contain the original, unmodified user object.

I suggest to open a discussion or ask on our discord if you need furhter assistance. but this is not a bug, so I'll close the issue.

avatar
Mar 2nd 2023

@LinusBorg OK I see. Thanks for your help!