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

$attrs missing property when used with v-model #8430

Closed
dattn opened this issue Jun 29, 2018 · 13 comments
Closed

$attrs missing property when used with v-model #8430

dattn opened this issue Jun 29, 2018 · 13 comments

Comments

@dattn
Copy link

dattn commented Jun 29, 2018

Version

2.5.16

Reproduction link

https://codesandbox.io/s/106qozol1j

Steps to reproduce

In the component TestA the value is passed as prop => the key value is present in the $attrs variable

In the component TestB the value is passed as v-model => $attrs is empty

What is expected?

The key "value" should be present in $attrs variable

What is actually happening?

$attrs is empty

@posva
Copy link
Member

posva commented Jul 1, 2018

In the component TestA the value is passed as prop => the key value is present in the $attrs variable

If you don't declare a prop, it will always be considered an attr, that's why it's there

In the component TestB the value is passed as v-model => $attrs is empty

v-model extends into a prop, you need to declare the value prop to see it in $props

offtopic: $props should be empty objects instead of undefined to be more consistent with $data, $listeners, $attrs (cc @chrisvfritz )

@posva posva closed this as completed Jul 1, 2018
@dattn
Copy link
Author

dattn commented Jul 2, 2018

OK, so i need to change my code a bit :(

But i have some more questions on this topic:

I changed my example, to be more clear.
https://codesandbox.io/s/7o2jjmovv6

The docs say the following:
https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components
v-model behaves the same as the combination of v-on and v-bind.

This is the case when i define the prop, but not when i do not define the prop. Why is there a difference ?

What i want to do is to forward the v-model to a child component with a little as possible of code.
Here an example:
https://codesandbox.io/s/23mm7omk1j
In this example i tried to forward v-model to the "ChildWithModel" component.
When i understand correctly i must add the prop "value to the parent, and create a computed value with the combination of $attrs and that prop ?
Which will result in the following code:
https://codesandbox.io/s/6z33pyq0mn
Is this the only solution ? This is much boilerplate code ....

@posva
Copy link
Member

posva commented Jul 2, 2018

v-model cannot create the prop for you on the child component. You must add a prop named value to a component in order to make it support v-model

@dattn
Copy link
Author

dattn commented Jul 2, 2018

So v-model does more than only mapping to v-bind and v-on :(
I will search for another solution.

@posva
Copy link
Member

posva commented Jul 2, 2018

no, that's the point, it only does that. And because it is done outside of the component, it cannot add a prop to the definition of the component it is used on

@dattn
Copy link
Author

dattn commented Jul 2, 2018

Then i do not understand, why there is a difference in my first example "Without prop"
https://codesandbox.io/s/7o2jjmovv6
For "Without v-model" i added the v-bind an v-on, on my own.
For "With v-model" i used v-model.
And the result is clearly not the same.

dattn added a commit to IONlu/vue that referenced this issue Jul 2, 2018
@dattn
Copy link
Author

dattn commented Jul 2, 2018

With this change, the behavior is exactely the same as with v-bind and v-on.

@LinusBorg
Copy link
Member

@dattn That looks interesting, thanks

/cc @posva I think this could work!

@LinusBorg
Copy link
Member

reopening for visibility

@LinusBorg LinusBorg reopened this Jul 2, 2018
@posva
Copy link
Member

posva commented Jul 2, 2018

Yes, this could work, I think it makes it more consistent.

dattn added a commit to IONlu/vue that referenced this issue Jul 2, 2018
dattn added a commit to IONlu/vue that referenced this issue Jul 3, 2018
@vuejs vuejs deleted a comment from aiplat Sep 14, 2018
@fjc0k
Copy link
Contributor

fjc0k commented Sep 14, 2018

This will make it easier to create a high order component. Before PR is accepted, we can use:

{
  computed: {
    $attrsAll() {
       return {
         value: this.$vnode.data.model.value,
         ...this.$attrs
       }
    }
  }
}

@fjc0k
Copy link
Contributor

fjc0k commented Feb 7, 2019

fixed: b034abf

@franciscolourenco
Copy link
Contributor

Is there a way to fully bind v-model without having to emit events from the child component?

I'm looking for a easy way to customize 3rd party components, perhaps with custom styles and/or default attributes.

I'm currently binding $attrs, however emitting events is still necessary.
https://codesandbox.io/s/8z2vz53v22

Is there a more elegant way to achieve this, perhaps using extend? We can use scoped styles instead of the custom class. What about the default props/attributes?

Thanks!

@posva posva closed this as completed Sep 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants