There are three main ways to store variables and/or react to variable changes in Vue components.

  • data
  • computed
  • Watch for changes in watcher

So, how to decide when to use what? (that is 3-in-1 question, I outwit myself)

Although these sections look similar, they serve different functions. Evaluate the variables against the following considerations when you are in doubt.

DescriptionDataComputedWatcher
Store variablesStore local variablesComputed variables. Can be static, derived from other variables, or can be static functionsDoes not store variables - only watches them.
React to variable value changesYYY
Cached?YYN/A
ScopeLocal to componentLocal to component, but can derive/make calculations with variables from props, store, etc.Can watch local or store variables and react to changes
Can be referred by <template>Y
e.g. {{ myName }}Y
{{ myCalcName }}N/A
Can be referred by <script> methodsY
this.myNameY
this.myCalcNameN/A
Perform action when value changesNNY
Consequence of a value changeChange UI to react to changeChange UIPerform action - local/vuex
Can change other variable valuesNYY

See examples below.

Data

Data is a function in the component and can have one or more variables. Scope of these variables is limited to the component. Variables can be initialized to a value, or just assigned a type.

<script>
  export default {
    data() {
      return {
        valid: true,
        num: 123,
        name: "Neo",
        status: String,
      };
    },
  };
</script>

Computed

Computed is an object within a component, and can have simple variables, or functions.

<script>
  export default {
    computed: {
      // refer to state or getter from store
      ...mapState("todo", ["numTodo"]),

      // not sure why you would want to do this, but ok.
      sumZero: 0,

      // sum as a function
      sumSum: () => {
        return this.num1 + this.num2;
      },

      // function that calculates value from other values
      // called simply as this.fullAddress or {{ fullAddress }}
      // also a function
      fullAddress() {
        let addr = this.contact.address_1 ? this.contact.address_1 + ", " : "";
        addr += this.contact.address_2 ? addr + this.contact.address_2 : addr;

        return addr;
      },

      // can be updated and retrieved through get/set
      sumTotal: {
        get() {
          return this.num1 + this.num2;
        },
        set(value) {
          this.total = value;
        },
      }, // sumTotal
    },
  };
</script>

You can see that a method can also calculate values similar to computed and those calculated values can then be stored in data. But computed has two big advantages -

  1. Values are cached. You don’t need to do anything other than store values as computed. Computed values are picked up from cache when there is re-render. Methods, on the other hand, are always run whenever re-render happens - thereby causing computations to occur even when the source has not changed
  2. React to changes. When source is changed, the computed values automatically change - there is no need for a separate watcher

Watcher

<script>
  export default {
    watch: {
      // react to changes
      // calculate other variables
      startDate: function () {
        this.endDate = this.startDate + 10;
      },
    },
  };
</script>
Further Reading

Go to the excellent Vue documentation on computed properties vs. watchers