Skip to content
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

v-model.sync to automatically emit a prop's changes as an event #8403

Closed
dylanized opened this issue Jun 23, 2018 · 5 comments
Closed

v-model.sync to automatically emit a prop's changes as an event #8403

dylanized opened this issue Jun 23, 2018 · 5 comments

Comments

@dylanized
Copy link

dylanized commented Jun 23, 2018

What problem does this feature solve?

v-model is a helpful tool, but it doesn't work in nested components. Instead we are supposed to use v-model on a parent component, then manually bind props and manually emit a change event within the child component. This is too verbose.

Instead, I am proposing an option for v-model that automatically emits the change event.

What does the proposed API look like?

Template for the parent component:

<div>
  <custom-input v-model='foo'></custom-input>
</div>

Template for the child component:

<div>
  <input type='text' v-model.sync='foo' />
</div>

AS AN ALTERNATIVE TO:

Template for the parent component:

<div>
  <custom-input v-model='foo'></custom-input>
</div>

Template for the child component:

<div>
  <input type='text' :value='foo' @input='$emit("input", $event.target.value)' />
</div>
@HcySunYang
Copy link
Member

HcySunYang commented Jun 23, 2018

The child component's input tag may have its own v-mode binding, and according to your idea the .sync modifier seems to emit only input events.

@dylanized
Copy link
Author

dylanized commented Jun 23, 2018

I'm just hoping to suggest a clean way to extend the v-model connection up to the parent, without having to manually write an emitter. Apologies if my example implementation isn't perfect.

In my idea, the v-model.sync variable be set as a prop, which got passed down from the parent. So there couldn't be a local v-model binding for that name.

@posva
Copy link
Member

posva commented Jun 24, 2018

Although the feature is interesting, it is still convenience over a thing that is already made for convenience. There is also a major flaw: this would mean that a v-model could modify the component it is used on by creating a watcher or something similar. Which is currently not possible

To me it looks like you want an easy way to setup a prop that is meant to be used with v model or sync. I recommend you to give a look at computed setters

@bandleader
Copy link

Related: vuejs/rfcs#11 does the same but just for events, not for two-way binding.

Note: the name of the modifier .sync is out of place here. What you're looking for is more like .pass, or perhaps a directive v-pass.

Explanation: :foo.sync="expr" is actually akin to regular v-model -- it expands to

:foo="expr" @update:foo="expr=$event"

i.e. it catches the event and updates the state, just like regular v-model, which does

:value="expr" @input="expr=$event"

What you're looking for is

:value="expr" @input="$emit('input', $event)"

@bandleader
Copy link

I commented there as to why this cannot be solved with a directive.
vuejs/rfcs#11 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants