Open jods4 opened 1 week ago
Additionally, the onMounted
of the Wrapper.vue
is also called after onBeforeUpdate
. see Playground, Observe the console logs.
A simpler minimal reproduction
We can see that the breakpoints in setTimeout, beforeUpdate, and mounted are triggered in sequence
Vue version
3.5.13
Link to minimal reproduction
https://play.vuejs.org/#eNp9VE1vEzEQ/SuWL03VZFMUeglJBFQ5wAGqtogDRmizO9m48dorfyxBq/3vjL1foSS52TPP4zfznl3RD0URlQ7onC5MonlhiQHrCiJimS2tWTHJ80JpSx7iDMhWq5wwGk39zp9jtAdUxOxiIdTvR9iSuoO2GCYTJY0lha+yPEKOpBPimkm89ZnnoJwdja7JchWQURkL5/H+ujG5u71F5GLaEEVquLGQFyK2sCKESUIW9wrZSJCWzLlZMurLMEqmiF5MezCTdEytQU5bnkUvRkkcQOULMJpgBS5Afy0sR86MzknI+Fxg/TnErHYw7uLJDpL9ifiLOfgYow8aDOgSqfQ5G+sMbJNeP32BA677ZK5SJxB9IfkIRgnnOTawj06mSPsIF9h+CupwmT2b9cGCNF1TnqhH1gEflPLDO9f6QHcWvQ3nmKxxit91XBSgz5sIj2KlwUgV0f8Z5N3gEJQcBUfIiNGNyxhFyZtMopy0oNustwKTWycTz5Uo+eSvRO8ExlilN8+V2l8h17POCb5JeRkW/yxxw2XhkNQEZw4Ce8GiaCf7pwDcGIh1sgv2QksrJ1KyAeypqkIbde2tH8pMz9T/ZqDvyyrfGBplh6HWxShA1QPqOng8FNk4a7Ht94ngyR6ptJibGxw1l0m0mDaI7tIjAm3ECIWPpJ1beCAD7PVTud9xkZ6SGNONOJBzi7NOYcslrHFjRj/8gBDD6E/UygNQ0jZy/h2/UiPcfIla9xOdYNYarnXo8HkdWfbo/wo3DaC+ZQ+5xLUrX078RFGK2FrdOD7MualbTjZcpkO2H3h7/ERnv0rQ/rViZ7PoLnozo/VfG1jmXA==
Steps to reproduce
Just open the repro.
What is expected?
The result should show
[ ok ] should be "ok"
.What is actually happening?
The result shows
[ bug ] should be "ok"
. Clicking on button "inc" will force a new render of the component, which will fix the page.System Info
Any additional comments?
This reproduction is extremely fragile and I had a hard time creating it. The core of the issue is incorrect queued hooks execution order, and most changes you would do to the repro are going to fix it. If you want to see the page working correctly from the get go, just remove the timeout in
App.vue
and directly setpage.value = Page
.Here's what I found out when debugging this myself:
The input is driven by a
v-model
, so the value is not really "rendered" by script setup, but it's instead set on elements byvModelText
core directive. This will explain why the interpolation{{ val }}
is rendered with the correct value, whereas the<input>
shows the initial value instead.The reproduction is setup in such a way that
vModelText
hooks are called in incorrect order. After eventonSetup
is processed byWrapper
, the component is rendered again, andvModelText.beforeUpdate
is called with the new value. If you break at this point you'll see the repro displaying the correct values.But then, it looks like the directive
mounted
hook has not been executed yet. It is enqueued by Vue coremountElement
function here: https://github.com/vuejs/core/blob/fc4bbf95c1f9c8d9591e82571008578da15d7677/packages/runtime-core/src/renderer.ts#L715-L725The issue seems to be that this call has captured the initial directive value and so restores the previous, incorrect value into the input element.