-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
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
update v-model reference synchronously #8652
Comments
Was the sync modifier removed in Vue 3? I can't find docs about it - I'm looking for the raw render fn version of it. |
If I understand the migration guide correctly, it sounds like I could be doing |
I am going to close this as I no longer need this feature. I used the "created" hook in a custom directive instead of the "onVnodeBeforeMount" VNode hook. The problem was that the application event listener and the internal event listener were added to the same element, but the application event listener was added first. This caused the reactive reference to be updated too late since the internal event listener fired after the application event listener. The application event listener is added first here: core/packages/runtime-core/src/renderer.ts Lines 660 to 670 in edf2572
And then the internal event listener is added after here in the core/packages/runtime-core/src/renderer.ts Line 686 in edf2572
Using the directive fixes the issue because the "created" hook is fired before the application event listener is added: core/packages/runtime-core/src/renderer.ts Line 652 in edf2572
|
What problem does this feature solve?
Vue components with
v-model
that wrap Web Components have theirv-model
reference updated a few frames after the associated event fires. This can be confusing as logging the model value in the event callback shows a stale value.Example
Link: https://play.vuejs.org/#eNqdVk1v2zgQ/SuEsIDkwJYO3ZNrB9lms9gu2m7RBslFh8rS2FYrkVySchIY/u87HOqDkt2iqA+GRM7Xe5x51DH4Q8r40ECwDFY6V6U0TINp5HXKy1oKZdiRoclbLhvDTmyrRM3COOmWwteenYJtb4Ih7V7Kc8G1YaU1fsiqBtja2kVhOPO2Bb9ttBG1S7NmERxmbH3NjilnzJqICuJK7KLwE+agOOHcCxof7L+NeLJBV4mDgiDwxUAtq8wAvjG26sEcFrUooFqnwRAnDdhNTpXQGu6NKot+gwNwM0uD61VPAYZdJV6OYB44RhZ1JuOvWnDkloBgJtrQabB00OwaMmXf02BvjNTLJMkLjm5YWnlQMQeTcFknN2iWqIabsoZFIeqbV/Gr+PekKLXxl2PQ9WKjxJMGhUHSYO6lSXDxAGqhgBegQP1s2ombn3qydZbeZscjOSEpRuNBbsvdhJJc1LKsQP0rTYkHPaImqyrx9A+tGdVAjyXfQ/7twvpX/ewwfVRAlXn4TaZ2YNz23ecP8IzP/SZ2QlO1x/CdzU+ATdjYGp3Zm4YXWLZnR9W+pRMu+e5e3z0b4LoDZQslNsiezuP2B9CHcpFtj8Wu62KjkcN+9HQlzF9VttP3WHs3hGngjm+fKSjSwB/VArYlpwIEx46es/3gRA05GJsXCejx8AGn5dwIJ7jKtO414vGWYQXYDpr9ff/+3V0FNcbvcI1kAAmkKgoKY7dJDFSTG6GiWedjf7qRgEtoaN9oxu0DMsRo8sfWCgVMcWb2pY6HjFNnlLnWGbXG8564YaGHvsC+SIcE98j6vwbUy2eogCoPaa/Vt86r3LKI1ke5ek6cgHXxzopuCx/V72ZujLz15qAs+Rjuy8oVag8R1cxQZ7Pk+ssvQxqXnRXFnZXEdygGgGk7yznDwjoBH34uUW6BcnhiTlopQBR6uovuR7ZpNpsKtJscdvJzD/lRhGRm8r2LkdMV0BM26pe+wzhCguIWp3WT5d8u8NcRO3hTAHimcXAQ+ltkPR2lKJJKSG0RQF3iLPo8JAn7k8wxE7BH2LDez3YIF4ZllYKseGnDFu3cYPc4ftqB0jH2fhRmUi7ao2HrtTdSI1QTT2fiO8+98T0bsgrnhG7Kj4irG4nQXe6E6eqqTXXFHvfArT4PR4ndti1RjfGKP8fc+z0B9gMUzAjWyALvUbJtb2j7vYCXC88h7hwSTy8w8gNHuzewFQreC7wM7RfEwa4tnWxNW5H2YqgutO+4CyOMQAaXmvmMlAhiJ9ssc+pHlLa8z9yIT7rYtkgUOsxLCth93IyjX+7r12wQA5K8s6Fr1/fj0z5e4GzuxHA5heVPET4Hp/8BxkJXEg==
This example shows an
AppInput
Vue component that renders anapp-input
Web Component.The application sets the
v-model
ofAppInput
using theinputValue
ref. The value of this model is passed to theapp-input
Web Component where the value is then set on the<input />
element that it renders. Whenever the user types in the text input,inputValue
should be updated with the value of the text input.The model is updated in
AppInput.ts
by callingemit('update:modelValue', ev.target.value)
whenever the Web Component fires thecustominput
CustomEvent. While this works, it leads to a confusing developer experience. The reason for this is developers can add their owncustominput
listener by adding@custominput
on theAppInput
Vue component. Logging the value ofinputValue
logs a stale value becauseemit
updates the model asynchronously.Steps to reproduce the issue:
console.log
in arequestAnimationFrame
should log the latest value.Other Information
Vue has access to the model internally and is able to update it synchronously if Vue is the one rendering the
<input />
(see:core/packages/runtime-dom/src/directives/vModel.ts
Lines 47 to 59 in 020851e
core/packages/compiler-core/src/transforms/vModel.ts
Line 83 in 020851e
<input />
is rendered outside of the Vue context.vuejs/vue#7830 appears to be related.
What does the proposed API look like?
Ideally I'd be able to do something like
emit('update:modelValue', ev.target.value, { sync: true })
. I don't need access to the model ref itself.The alternative approach is to use two events which is what I am doing now, but it is hard to maintain and error prone. For example, the
app-input
Web Component would fire thev-custominput
event. TheAppInput
Vue component would listen forv-custominput
, update the model usingemit
, and then callemit('custominput')
so developer callbacks that listen forcustominput
are fired after the model has been updated.The text was updated successfully, but these errors were encountered: