Originally posted on dev.to

Vue is shipped with two ways of storing variables. One way is to use props, and the other way is to use data. Both of them can be defined on the Vue instance, as well as on the component.

At first, they might look confusing since they are very similar and seem to serve the similar purpose.

In this article, I will try to distinguish them and hopefully the difference will be more clear.

Props

Props are the way of how we can pass the data from a parent component down to any of its children.

When we build an application with Vue, we are doing it in a hierarchical way. What does this mean? It means that, starting from the Vue instance, the data flows from top to bottom and each data variable created on a parent can be passed down to its child via property.

The props can be defined as a an array of strings (names), but this will not cover the validations for the value passed to it. If validation is desired, an object needs to be listed with some specific configuration.

Also, good thing to point out is that we can pass a dynamic or static value to each of our properties.

Props as an array:

export default {
  name: 'my-component',
  props: ['name', 'surname']
}

Props as an object:

export default {
  name: 'my-component',
  props: {
    name: String, // must be a string
    surname: String, // must be a string
    propA: [String, Number], // allows multiple types
    propB: { // required string
      type: String,
      required: true
    },
    propC: {
      type: Number,
      default: 15 // the default value
    },
    propD: {
      validator: function (value) { // custom validator function
        return true
      }
    }
  }
}

If we run Vue in development mode, it will throw a warning each time when a prop type is invalid. In production mode this is not the case.

Ok, now when we know how to define the props, we should see how we can pass a value to it. This is done through the template.

Template:

<template>
  <div>
    Name: {{name}}
    Surname: {{surname}}
  </div>
</template>

We can pass a static value:

<my-component name="John" surname="Doe"></my-component>

or, if dynamic value is desired, we need to use v-bind directive:

<my-component v-bind:name="dynamicName" v-bind:surname="dynamicSurname"></my-component>

Note that camelCased properties need to use their kebab-cased equivalent. However, this limitation doesn't apply if a string template is used.

After all this being said, we should point out the importance of respecting one way data flow.

All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around.

This means that we don't need to worry about whether our child component property has the latest value from the parent. The props are reactive and this is all done for us. The Vue will make sure that each property has been updated after changing the parent value. If we try to update the child value by ourselves, the framework will throw a warning in the console.

Data

Data is the private memory of each component in your app where you can store any variables needed by it.

The data object is like the schema for your component’s state

In other words, we should use data config for the variables that are going to be used by the corresponding component only. If we need to pass this data to another component, we need to use props to pass it down to the children, or events to pass it up to the parent.

Our data should be configured as a function which returns an object where each property represents a variable which will be available within our template. By defining a data property as a function we are making sure that each instance of the component has its own copy of the data object.

<template>
    <span>{{message}}</span>
</template>
export default {
  name: 'my-component',
  data() {
    return {
      message: 'Hello!'
    }
  }
}

In the example above, if the message property wasn't defined as a data variable, the framework would throw a warning that we are trying to use something that does not exist.

Each variable defined within the data object will be reactive. This means that, like in the props example, we don't need to worry about value and template updating. This will be handled by the framework every time when the corresponding change occurs within our application.

Basically, as long as we are updating a reactive property (props, computed props, and anything in data), the framework will handle the updates for us.

Wrapping Up

Although props and data are similar, the difference at this point should be a little more clear and that they are meant to be used together in order to build a proper data flow within our application.

I would say that this line points out the key definition:

Both data and props are reactive, but data is more like "my own specific genes I've received when I was born" and props are "I expect to get these genes from my parent."

Thanks for reading and see you in the next article.