data property in component must be a function

Why Vue.js data property in component must be a function?

If you are a newbie (or maybe not, but just clumsy enough), you probably had this error at some point: `data` property in component must be a function. This occurs when you are returning a data object without a function. Even though it is mentioned on the official documentation , the explanation might sound difficult for someone who is just making his first steps with Vue.

This is what Vue.js documentation states:

data option must be a function, so that each instance can maintain an independent copy of the returned data object:

Let’s see what does that mean.

Why does data must be in the function?

Vue components are static, so this is the reason why every component must have a data object. If not, then the all components would be able to access the same data. And if we changed the data, then it would change for every component.

This is one of the precautions that framework takes to preserve the state of a component. Every Vue component have it’s internal state, and if you have few instantiated components, every of them has an internal state. It is possible because of this feature that function returns an object.

How to fix the error?

Firstly, let’s see how can we fix this. Error is self explanatory and it says what you need to do – put the data in a function. So all you need to do is return the data in a function, so if your code looks like this:

<template>
  <div id="app">
    <button>{{ buttonName }}</button>
  </div>
</template>

<script>
export default {
  name: 'app',
  data:  {
      buttonName: "My name is button"
  }
}
</script>

All you need to do is to put everything inside a function:

..............
<script>
export default {
  name: 'app',
  data: function () {
     return {
      buttonName: "My name is button"
     }
  }
}
</script>

This is how data in error could be passed:

<template>
        <ul>
            <li v-for="message in messages" v-bind:key="message">
                {{ message.message }}
            </li>
        </ul>
</template>

<script> 
export default {
    name: 'App',
    data: function () {
        return {
            messages: [ 
              { message: 'First message' },
              { message: 'Second message' },
              { message: 'Third message' }
            ]
        }
    }
}
</script>

Note: without “v-bind:key=”message” you would get Elements in iteration expect to have ‘v-bind:key’ directives error.

Leave a Comment

Your email address will not be published. Required fields are marked *