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

Warn when component option should be an object, but is a function #5605

Closed
phoenixeliot opened this issue May 4, 2017 · 6 comments
Closed

Comments

@phoenixeliot
Copy link

What problem does this feature solve?

I often get mixed up on which properties of a component should be functions and which shouldn't, and mistakenly define some as functions when they should have been objects.

In the opposite scenario, when a property that needs to be a function is instead an object, we already get a very helpful warning message:
[Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.

But if you define the watch, methods, created, or computed properties (and probably some others) as functions instead, Vue either silently fails to use the property at all, or gives a confusing error message. I've spent an embarrassing amount of my Vue dev time because of this simple mistake.

Here's what those ones do if the value is a function instead of an object:

watch will simply be ignored if it's a function instead of an object.

components will prevent any children from rendering and log this message: Unknown custom element: <child-component> - did you register the component correctly? For recursive components, make sure to provide the "name" option. (found in root instance)

methods will cause a runtime error with this message: [Vue warn]: Property or method "someMethod" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in root instance)

computed — similar error methods

Most of these errors are at least somewhat misleading as to what the real problem is.

The main benefit of a warning for this kind of mistake would be to spend less time futzing around with fixing the boilerplate after getting it slightly wrong.

What does the proposed API look like?

If a component is initialized with any properties whose values are functions, but should be objects, emit a warning similar to the warning for data. eg:

[Vue warn]: The "computed" option should be an object, not a function, in component definitions.

@phoenixeliot phoenixeliot changed the title Warn when property should be an object, but is a function Warn when component option should be an object, but is a function May 4, 2017
@posva
Copy link
Member

posva commented May 4, 2017

There's nothing to be embarrassed by 🙂
What interests me more is why did you think using an object instead of a function or vice versa should have worked in any of those properties. Dev warnings are cool but they do have a cost to maintain and at execution too. I thought the docs covered that quite well

@posva
Copy link
Member

posva commented May 5, 2017

ping @phoenixeliot

@phoenixeliot
Copy link
Author

phoenixeliot commented May 5, 2017

It's less a lack of understanding and more going through the boilerplate a little too fast, and then later on when actually using the options, things fail in ways that aren't clear.

When making a new component, I'll just throw in the common options to start with, then fill them out later, just to take the mental overhead out of remembering exactly what they're called. (We haven't been using Vue for terribly long, so I don't have them down by heart yet).

Also, side note: We use CoffeeScript. But I think in ES6 notation it could look pretty similar.

So I'll throw together a new component and it'll look something like this (when done right):

SomeComponent =
  name: 'some-component'
  template: require('templates/some-component')()
  storeModule: SomeStoreModule
  props: {}
  data: ->
  computed: {}
  watch: {}
  components: {}
  methods: {}
  created: ->
  destroyed: ->

And it's easy to not notice if I put a -> instead of a {} on one of those that should have a {}, because it works perfectly fine for now — it just breaks when I try to actually use them. Say I'd had a -> on watch:

SomeComponent =
  name: 'some-component'
  template: require('templates/some-component')()
  storeModule: SomeStoreModule
  props: {}
  data: ->
    bar: "yay"
  computed: {}
  watch: ->
    bar: ->
      console.log(@bar)
  components: {}
  methods: {}
  created: ->
  destroyed: ->

But then when I change bar, the watcher just... doesn't run. And it's not super obvious that this is the reason why. It always feels like a gotcha when I eventually figure it out.

Also note: This usually happens like, the next day, when I'm adding some new functionality, and thus don't have the boilerplate fresh in my head and am (erroneously) assuming it works because I hadn't seen any problems.

yyx990803 pushed a commit that referenced this issue May 12, 2017
…5642)

* warn when component should be an object, but is not

* remarks

* remarks

* remarks

* rename to checkOptionType and guard production

* typo

* Update state.js

* Update test-object-option.js
@Kingwl Kingwl closed this as completed May 28, 2017
@Mostafa123sh
Copy link

you must put your data inside bracket and then return it

@Mostafa123sh
Copy link

like this:
data(){
return{
names:["ali","ahmad","Raza]
}
}

@olsonpm
Copy link

olsonpm commented May 12, 2018

What interests me more is why did you think using an object instead of a function or vice versa should have worked in any of those properties

If properties that needed to be functions had verb prefixes e.g. createData instead of data then there would be little to no confusion. What would be even better is if vue got rid of this inside their functions and just added it as another parameter - then its documentation could remove all those warnings about what functions do and don't support this. Additionally there would be fewer invalid bugs reported.

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