-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Simplifying the transparent wrapper pattern #9
Comments
Actually with v3's flat vnode data implementation, declaring props is unnecessary. When you pass data down it doesn't matter if it's a prop or not. So the wrapper can simply do <input v-bind="$attrs"> Regarding the input event re-emit, I kinda want to avoid this event vs. value mismatch altogether. Maybe the code |
Yay! 😄
I think that'd be great, but I still feel like the default event for components should be Making
|
@chrisvfritz yeah, I agree regarding emitting Making One possible implementation: <input v-model="foo"> h('input', {
modelValue: this.foo,
'onUpdate:modelValue': value => {
this.foo = value
}
}) When used on a component:
When used on an element, the runtime will dynamically transform
This way, |
@yyx990803 Brilliant! I love it. 😻 A few follow-up questions:
With those final tweaks, I think we might actually have the perfect
|
I just edited my proposal a bit. When used without an argument the generated props should not care about what key it is. When used without an argument: <input v-model="foo"> h('input', {
modelValue: this.foo,
'onUpdate:modelValue': value => {
this.foo = value
}
}) When used with an argument it will compile like this: <Comp v-model:someProp="foo"> h(Comp, {
someProp: this.foo,
'onUpdate:someProp': value => {
this.foo = value
}
}) So I don't think it makes sense to use |
@yyx990803 I agree it doesn't make sense to use <InviteeForm
v-model:name="inviteeName"
v-model:email="inviteeEmail"
/> where <script>
export default class InviteeForm extends Component {
static props = ['name', 'email']
}
</script>
<template>
<form v-bind="$attrs">
Name: <input v-bind="{ modelName, 'onModelUpdate:name' }">
Email: <input v-bind="{ modelEmail, 'onModelUpdate:email' }">
</form>
</template> Though maybe we could actually abstract away the implementation details of: <input v-bind="{ modelName, 'onModelUpdate:name' }"> by simplifying to something like: <input v-model.prop="name"> What do you think? |
Sorry. Why not use |
@Jinjiang I don't think I understand the question. Could you elaborate? |
Sorry for my bad description. 😅 As we discussed above, now <input v-model="foo"> will equal to: h('input', {
modelValue: this.foo,
'onUpdate:modelValue': value => {
this.foo = value
}
}) not: h('input', {
value: this.foo,
'onUpdate:value': value => {
this.foo = value // or `value = value instanceof Event ? value.target.value : value`
}
}) right? So my question is why we choose the name |
@Jinjiang Ah, I see. If I understand correctly, it's because |
Closing in favor of vuejs/rfcs#8 and vuejs/rfcs#31 |
The transparent wrapper pattern is very convenient and increasingly common, but still a little clunky in Vue 2.x. For example, to get a
BaseInput
component that can be used exactly like a normalinput
element, we need to do this:In Vue 3, that will currently translate to:
Still quite a bit of work. 😕
However, if we remove
v-model
's assumption thatvalue
is a prop, then it no longer has to be added separately. And if we also makev-model
listen for anupdate:value
event by default (as @posva suggested here), instead ofinput
, then we no longer have to overrideinput
and can just add a new listener.With these 2 changes, our
BaseInput
component would simplify to:To me, this is much more convenient and intuitive. 🙂
@yyx990803 @posva @johnleider What do you think?
The text was updated successfully, but these errors were encountered: