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

Computed property setter on component other than "this" not called when updating v-model #6908

Closed
wcoene opened this issue Oct 25, 2017 · 4 comments
Labels

Comments

@wcoene
Copy link

wcoene commented Oct 25, 2017

Version

2.5.2

Reproduction link

http://jsfiddle.net/pLvn7o95/

Steps to reproduce

  1. Declare a computed property on a parent component, with a setter
  2. In a child component, pass the computed property as a v-model
  3. Attempt to update the property via the v-model binding

What is expected?

The computed property setter is called.

What is actually happening?

The computed property setter is not called and the following message appears in the JavaScript console:

[Vue warn]: Avoid adding reactive properties to a Vue instance or its root $data at runtime - declare it upfront in the data option.


This appears to be a regression in Vue 2.5.0, as changing the Vue version in the provided jsFiddle to 2.4.0 fixes the bug. The optimisation applied earlier in the 2.x-series to declare computed properties on the component's prototype appears to interfere with the call to hasOwn in function set (in observer/index).

@wcoene
Copy link
Author

wcoene commented Oct 25, 2017

I've found a change in parseModel which might be the culprit. Prior to this change, v-model bindings in the form 'foo.bar' would not be rewritten to '$set(foo, 'bar', $$v)'.

Relevant issues: #5932 and #6734.

@yyx990803
Copy link
Member

Either way using v-model like this (directly on $parent) is not recommended...

@wcoene
Copy link
Author

wcoene commented Oct 25, 2017

I understand. However, my reproducible isn't really reflective of what I'm trying to accomplish.

I have written a simple data grid, which accepts arbitrary Vue template strings to render column contents with. For the header column, I'm rendering a checkbox whose data is to be bound to a computed property on the containing component (the one that instantiates the data grid). This checkbox reflect the selected state of all rows in the grid, and changing should update the underlying selection flags on each of the rows.

I've implemented this by declaring a method findParent via a global mixin, which looks for the offending parent component, and then accessing the computed property like so:

<checkbox-field v-model="findParent('planning').allesGeselecteerd" :disabled="!findParent('planning').canEdit" />

Prior to 2.5.0 this worked nicely; however, when updating to 2.5.2 this code broke.

I do have a workaround: turning the computed property in question into a data property, and using a watch to sync its value with the individual selection flags. But that's hardly ideal.

@yyx990803 yyx990803 added the bug label Oct 25, 2017
@yyx990803
Copy link
Member

This is coincidentally fixed in 83ed926

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

No branches or pull requests

2 participants