Directives mounted called *after* beforeUpdate #12460
Labels
🔨 p3-minor-bug
Priority 3: this fixes a bug, but is an edge case that only affects very specific usage.
scope: v-model
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 event
onSetup
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:core/packages/runtime-core/src/renderer.ts
Lines 715 to 725 in fc4bbf9
The issue seems to be that this call has captured the initial directive value and so restores the previous, incorrect value into the input element.
The text was updated successfully, but these errors were encountered: