-
Notifications
You must be signed in to change notification settings - Fork 546
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
Should v-model-* directives be public? #156
Comments
In Vue 2, we used to do the second option i.e. manually handle attributes and events. Eventually, a Babel transform for As soon as the JSX plugins are completed, I can see it becoming supported in Vue 3 as well. |
It's nice that there is an official way but we don't use JSX here and we are not really considering it for now -- although that may not be a total blocker. On the other hand, our pipeline is Typescript for transpilation into Webpack for bundling. A Babel plugin is out of question for us. (We currently go with 1) |
TypeScript and Babel are not incompatible here. TS allows you to preserve JSX for further transpiling. Actually, Vue CLI 3's TypeScript emits ES2015 code and pipes it to Babel plugin. |
It's not a compatibility problem. It's that it's totally out of question for us to pipe Babel into our build pipeline just for that. |
Built-in vModels are bound to HTML native elements, so in order to reuse them you'll have to place them on these elements. So exposing their logic out doesn't really make sense since you can't apply it to any arbitrary element. The problem with v-model is that it is a two way binding and will mutate state. That means you can't directly use it on a prop. To actually be able to do so you'll have to work with computed getter and setter. |
@CyberAP I don't understand your answer. I'm saying it's an unfortunate limitation that I can compile this html template: <input v-model="name"> but I can't write a JS render function that performs the same. Actually, I can but it's not officially supported: function render() {
return withDirectives(
h("input", { "onUpdate:modelValue"(v) { name = v } }),
[ [ vModelText, name ] ])
)
} |
But doesn't vModel automatically pick which model to use? function render() {
return withDirectives(
h("input", { "onUpdate:modelValue"(v) { name = v } }),
[ [ vModelDynamic, name ] ])
)
} Providing some guidance on how to use it would be helpful, in that I agree. |
What I wrote works as well. I find it strange that |
That doesn't sound strange to me, it's a sort-of a facade pattern and works pretty well to abstract all the different vModels Vue uses internally. I don't see why end user should know about them because they are implementation details. You don't write |
@CyberAP you don't write There's a strong mismatch in Now my thinking here is: if Vue thinks |
Reading Evan's comment that you linked, I can't see any mention that |
@leopiccionia Assuming you're adressing me because you said "Evan's comment that you link": I don't. |
Update: By this commit, all |
It's great that there is now a very clear indication of what is exported but still considered internal and shouldn't be relied upon. It leaves the original question very much unanswered, though: there's no good and easy way to bind a textbox from a render function in the same way the compiler (template or JSX) does. |
Because there are now 2 other issues / PR that tackle "how to create components that wrap an input" I'm gonna add here my original use-case for this. I'm using the v-model internals to passthrough a Basically I'm doing this: <template>
<input
v-model-text.trim="$attrs.modelValue"
@onUpdate:modelValue="$attrs['onUpdate:modelValue']"
/>
</template> And my custom input can be simply used like: That's efficient and simple, although a bit obscure and relies on currently internal apis. Not saying it's the best way but there's a demand for simple model wrappers, see those alternative ideas: #175, #165, #140, #21 . |
@yyx990803 Looks like this was fixed by vue-next#1329, right? |
Yes. |
In this comment Evan pointed out to me that
vModelText
(and friends) is exported for the compiler only and is not public nor documented.Unless I miss something, this has an unfortunate consequence: you can't write a JS render function that binds
v-model
of an input.Because this template:
is compiled into the JS equivalent of this by the compiler:
and you can't do that transformation in user code if
v-model-text
is off-limits.Alternatives
Use undocumented apis 🤞
Drawback: risks breaking at any minor release.
Re-implement v-model yourself by compiling
Drawback: this is not trivial when implementing more complex features, such as modifiers
v-model.trim
, or other models e.g.v-model-checkbox
with an array.Drawback: far from pretty.
The text was updated successfully, but these errors were encountered: