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

Vue tries to observe enumerable but non-configurable properties #2393

Closed
saul opened this issue Feb 25, 2016 · 8 comments
Closed

Vue tries to observe enumerable but non-configurable properties #2393

saul opened this issue Feb 25, 2016 · 8 comments
Labels

Comments

@saul
Copy link

saul commented Feb 25, 2016

Vue.js version

1.0.16

Reproduction Link

https://jsfiddle.net/5sH6A/275/
Check JavaScript console for error.

Steps to reproduce

Add a non-configurable, but enumerable property to component data/props.

What is expected?

Vue.js should not be redefining properties that are not configurable in defineReactive as by virtue of being non-configurable, they cannot change anyway so observing them is pointless (and also throws an error).

This bug currently makes it impossible to add Three.js objects to Vue components without causing this error. However a current workaround is to set convertAllProperties = true, as this triggers checks to ensure that non-configurable properties are not redefined.

What is actually happening?

Uncaught TypeError: Cannot redefine property: <property name>

@Mat-Moo
Copy link

Mat-Moo commented Feb 25, 2016

FYI the fiddle is blank?

@saul
Copy link
Author

saul commented Feb 25, 2016

Thanks @Mat-Moo, updated the link

@yyx990803
Copy link
Member

It seems it's better to skip observing the entire object? I saw your other comment about a non-reactive object being converted when passed down as a prop. Maybe we need a way to explicitly declare non-reactive properties on a vm instance.

@saul
Copy link
Author

saul commented Feb 25, 2016

I agree that that would be a good feature, but think it should be separate to this fix, which fixes objects that you want to be reactive with some non-configurable properties.

I think the way to solve the 'non-reactive object' suggestion would be to never observe objects that are frozen (e.g., with Object.freeze), and can be tested with Object.isFrozen.

@simplesmiler
Copy link
Member

Maybe we need a way to explicitly declare non-reactive properties on a vm instance.

Yes please.

@yyx990803
Copy link
Member

@saul makes sense, let's work off #2394 to fix this.

On the other hand, Vue already skips observing objects that are not extensible. But the user may have objects that should not be observed but should be mutable. So maybe a new option like nonReactive?

export default {
  // reactive data
  data () {
    return { a: 1 }
  },
  // non-reactive properties
  nonReactive () {
    return {
      vector: new THREE.Vector3( 1, 0, 0 )
    }
  }
})

Basically, this simply attaches the property to the instance without converting it - in addition, it should probably add a private marker to the object (if it's extensible) so that when the object is passed down as a prop, it doesn't get converted again.

@yyx990803 yyx990803 added the bug label Feb 27, 2016
@Mat-Moo
Copy link

Mat-Moo commented Feb 27, 2016

For clarity should it be nonReactiveData so that it becomes an opposite to data? Maybe there could then be reactiveData (pseudo name for data)?

@Ben-Mack
Copy link

@yyx990803 Please consider to add nonReactive option. It will make working with external graphic lib much easier.

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

5 participants