.trim modelModifier behaves incorrectly on HTML input when it is applied on to component
Vue version
3.2.47
Link to minimal reproduction
Steps to reproduce
My reproduction link leads to Vue SFC Playground.
In my example the first input is an HTML element inside <App />
, the second one is from component <Comp />
.
To reproduce my issue, you need to do the following steps:
- Focus the first input field, enter several spaces one by one after the current text. Blur outside of the first input and focus in it again (as far as possible from the text).
- Focus the second input field, enter several spaces one by one after the current text. Blur outside the second input and focus in it again (as far as possible from the text).
Video example:
What is expected?
When passing .trim
model modifier to v-model
on Component with HTML input element after entering spaces in the input field, then blurring outside of it and focusing on it again the cursor position should be right after the text in the input, not after the spaces.
What is actually happening?
When passing .trim
model modifier to v-model
on Component with HTML input element after entering spaces in the input field, then blurring outside of it and focusing on it again the cursor is not right after the text but after the spaces that were entered.
System Info
No response
Any additional comments?
No response
I'm not sure whether it's possible to fix this in Vue itself.
It isn't just a problem for trim
. The same problem can occur with any v-model
modifier that generates a canonical form for the value.
In the docs, we have an example of a custom modifier, which has the same problem: SFC Playground. It might seem to be working correctly, but if you type hello
in the input, then select the H
and press h
, it'll get stuck on hello
, with a lowercase h
.
It happens because the canonical form of the value hasn't changed, so neither the parent nor the child re-render. The result is that the <input>
gets stuck on what was just typed, rather than showing the canonical representation.
It is possible to workaround these kinds of problems inside the component by manually syncing the <input>
value at an appropriate time. For example, with trim
you might do it with @blur
: example.
It gets fiddly trying to perform a similar update as the user types (which is probably what you'd want in the docs example I mentioned). Updating the <input>
makes the text cursor jump to the end.
I think .trim
should add to the input
of the Comp.vue
component. Because v-model in vue listens to native tags, not components
vModelText
Source Code:vModelText in line 43