-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(v-model): ensure initial value is set after other attributes
fix #2325
- Loading branch information
Showing
1 changed file
with
5 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54ed759
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose here is clear but I'm afraid of the unintended side-effects at larger scale.
I may not be 100% correct here, so please tell me if I'm wrong:
Before this change Vue users can assume that the lifecycle
mounted
event was a good time to do stuff after all bindings were set on target.I'm not affected by this but for example:
If I wanted to do a textbox that would scale its width to its contents I could have created a directive
v-autowidth
that would measure the size of the input content onmounted
.It would have worked fine before, after this change there's a race condition on which directive runs first.
This commit fundamentally change at which time in the lifecycle data is set and that could be troublesome.
I have no ready-made solution but wouldn't it be better to have a way to prioritize some values over other during the binding stage (i.e. have a way to ensure
min
,max
,step
happen beforev-model
)?54ed759
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directive appearance order is respected so you can simply put your directive after
v-model
. Special casing certain props is very hard to be comprehensive.54ed759
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the answer, so
<input v-model v-autosize>
would work but<input v-autosize v-model>
would not?Is this ordering guarantee actually documented? I don't remember seeing it.
I saw other issues where relying on the order of HTML attributes was discussed and participants were not very keen on taking ordering as granted (understandable).
EDIT: how does your answer extend to code other than directives that expect to be able to read a textbox value in
mounted
? E.g. what are the ordering guarantees if a generic composable function callsonMounted()
to similar effect?I don't see any easy fix for the problem that prompted this change but:
mounted
everything is bound" is still broken;v-model
set their value at the same time as this change only applies to<input type=text>
and<textarea>
.A mitigation could be to narrow down the scope of this change.
I believe of all
input
types, onlyrange
will coerce the value to its minimum (other will just be:invalid
), so instead of applying it to widely used text inputs, you could create avModelRange
for this fix?If we're going with "attribute order matters", wouldn't it be more "intuitive" (not the right word I'm afraid) to express the
min
/v-model
dependency that way?<input min v-model>
should work and everything is set whenmounted
runs?That makes the rule only matter for the narrow set of attribute that are actually inter-dependent (same behavior occurs in raw JS if you set
value
beforemin
) rather than modifying the common behavior of all text inputs. Also keeps themounted
contract intact.I think it's useful to think of a larger-scale recommendation because this may well not be the only time inter-dependent attributes exist.
A custom web element could well expose similar behavior as
range
/min
/v-model
and the "fix" in this commit doesn't generalize.