Subscribe on changes!

.trim modelModifier behaves incorrectly on HTML input when it is applied on to component

avatar
Mar 21st 2023

Vue version

3.2.47

Link to minimal reproduction

https://sfc.vuejs.org/#eNp9UstO6zAQ/RVf60oJUmPrPiSkKiAQQmLJChYYQWmmJRA/NHbCIsq/M3aaUkrVbOKZOTNnHqfnl86JrgU+56VfYu0C8xBad65MrZ3FwHqGsGIDW6HVLCNotg1dWe02fiGjEStRWJmlNT4w7dfsLKbn2Q00jWX3FpvqV3aiTClHNuIhI4B2zSIAWays6i7+6Stf/5z3PXt++t1TqeHpmQ1DKcm5CdfGtYF1hbYVNCJgrc8UJ6TiE+IFx1eZWj2EZDIhSjnSlnLbC5/xcc5CL5x489bQkvoIVpuAV3zOkif6aPZoK/4agvNzKVvj3tdiabW8oJjE1oRaQ1FZffFP/BX/T4nTh12/AK+LF7QfHpAYFZ/tFJfk7AALBFMBAh4l28N+I9yL/SCNnIMyAy1gOuoxeRAnnQGqPY1MInBonScZVLCqDdxGK3/I0iHuFg1BH0kOIxR0HbbIazIisnUVXWO+lzCldNFDOVMTeTrHGkJ+Ml0GqWE0Yx/iq0yaMu2XJspTnW1KbCQ/wDwb+Yh/3NBRIe8qOe7xkGhJhaniUR0On+YDP9I=

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:

  1. 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).
  2. 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:

https://user-images.githubusercontent.com/54540652/226659998-cac15cae-6e39-4720-8fd5-794775c65f9d.mov

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

avatar
Mar 21st 2023

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.

avatar
Mar 22nd 2023

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

微信截图_20230322161717