Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two-way binding can directly modify without emit 'update:model-value' event when using object to create ref() or reactive() #10729

Closed
ningwang723 opened this issue Apr 18, 2024 · 4 comments

Comments

@ningwang723
Copy link

ningwang723 commented Apr 18, 2024

Vue version

3.4.23

Link to minimal reproduction

https://play.vuejs.org/#eNqNUstu2zAQ/BWCFzuwK8dNT64c9IEcWqCtkRY9CSgUeeXQoUiCpFQHgv49S9KSpVgJciN3h8vZmanpZ6WiqgS6orHJNFOWGLCluk4EK5TUlnyVhSK5lgWZRAt3cfBJ1641pJllFcyJhrw5IgOEkERkUhhLMlkKS9YICeBp7Sury+ZiALmF3KPylwAbnjJxhFxiK14E1sgXLxYKxVMLeCMk9syrd4XcAl8ntP0goWQRAPe6PY1B/VdvBY/hmFClPQeGbl0fRWkat0XHnM5pK/JzTwhPxW5tzdCb5cCcpXfno1MjqOY//5vyElC1LeRMwA9Xmr5BvGWP/GlOtyqu0Jt+voc1SCFnu2hvpMBlap8IlKFQjIP+pSxDigldEd9xvZRz+f+7r1ldwrytZ/eQPYzU9+bgagndaDCgKyTX9Wyqd4B6u/bN759wwHPXROIlR/QrzVswkpeOY4B9KcUWafdwnu03bwUTuz/m5mBBmHYpR9QhG49PKBrjRH1p9RPdq+iDf5eI5pgG7+p4HPAhzkE/gt31yZGmM3yjpTJxr7UiqXhsrqcXGJTXQrBllT+Q+K60VgrMA8vdl48KZD7I1ppM5N0eMjvBfHzKOMseBqmJfNpnM+Q6ixdh3PPZwA2MvT17FdLXWxW1wkGLwLeXwkSggv8q0M4VFBCljd5f0eYJ4Aiuug==

Steps to reproduce

I show the code in playground.
when i create ref/reactive with Object and pass it to child component with v-model, it can directly modify without emit any event and it not trigger computed setter or watcher.

What is expected?

update value after emit 'update:model-value' event.

What is actually happening?

update value without emit 'update:model-value' event.

System Info

No response

Any additional comments?

No response

@quiteeasy
Copy link
Contributor

It seems that we can mutate a prop in the template, even though the Vue.js docs state there should be a warning if we try to mutate props in a child component. Interestingly, there doesn't appear to be a warning when a prop is mutated directly in the template.

Since the modelValue is also a prop, I believe this issue is closely related. I plan to open a pull request to add a warning when a prop is mutated in a template.

I've attached a link with a reproduction of the bug related to props. It seems the link to the documentation about readonly props may be lost during compilation.

I'm looking forward to your feedback and suggestions on this issue.

https://play.vuejs.org/#eNqtVE1v00AQ/SsjX+woxSYtp+BEfKgHkAoVIDhghFxnnDpd766863zI8n9ndu34I00LB272zNuZN2/ebuW8ldLflujMnVAlRSY1KNSlXEY8y6UoNLwXubyEtBA5uH5g/8wBtwNUBaZ1C2gSABFPBFcaElFyfcvijMMCCOe9nEQ8DJpO1IN+NOaSxRrpDyBsus3lInL6s5EDAaXDoMM6F45BnmMOLObrhVbjCWajCWZ2gtemf8MzFytk32NWIvFcYZpxvDEh7y9070qtBYftiywlxvogUaSjYgtwxd0GE+3SEG8SliUPBOwRvp1yOo2c5XQaBk29XooZlbbg0aFWD4CqGjar61ONtKLx0mztb5TgJFRld0PK5jJjWHyWOqPxI2cONmNyMWNi99HGdFHixTGe3GPycCa+UXsTi5zbAhUWWyLX5XRcrFE36euvn3BP312SiJeM0M8kv6ASrDQcG9i7kq+I9gBn2X6wa874+pu63mvk6jiUIWqQtcVHDi3diPrU6D3dK/+VPRfxunWadcx5q9FBqkP7aKxU9RupOzPdFkKqcJCaQ8wP9dKbkAmfM9gq29qP/2y1kdMGtZEpPHf20anGfYNRSSsqFDR8By6MeKugfTXOPDONatIINJbL++lK9xddwO6Slpoq/sj0vc0T2pvAYtks0BbwJRHl9hr8g6Tm+kjasqXeq9CNL6mDhCnMaPYb2xtMY6DH7FhxrOPjEieUTwrtKA5xkqBS5N5WA6reKrSLC05x7yBKgjJGkuExOBm/FU/o/nuLhbkNJDtZ2r+8cuo/RpQGhw==

@quiteeasy
Copy link
Contributor

The current behavior allows mutating a prop directly in the template, which could be considered a breaking change if we were to disallow it. Given that this is an existing functionality, we should carefully consider the implications before making any changes.

I'm looking forward to the team's suggestions on the best approach to handle this. We'll need to weigh the pros and cons of maintaining the current behavior versus introducing a warning or error when props are mutated in the template.

@ningwang723
Copy link
Author

ningwang723 commented Apr 18, 2024

I'm updated the code to add an input element to handle the prop "modelValue" in v-model, the prop should be readonly, but it can mutate even it in none setter computed!

Playground

@LinusBorg
Copy link
Member

LinusBorg commented Apr 19, 2024

Reative object's properties are always mutable in Vue, and always have been. When the docs speak of "props are readonly", it means you can't assign to a prop and have that change propagate to the parent:

const props = defineProps({
  title: String,
  user: Object,
})

// this doesn't do anything, and this is what we mean when we say "props are readonly":
props.title = 'New Title'

// this doesn't mutate the prop `user`, it mutates a property `name` in the object provided through the prop. 
// This always was mutable in Vue and is *not* a bug.
props.user.name = 'Tom'

You can create explicitly readonly reactive data though if you need to:

@LinusBorg LinusBorg closed this as not planned Won't fix, can't repro, duplicate, stale Apr 19, 2024
@github-actions github-actions bot locked and limited conversation to collaborators May 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants