Data vs Computed vs Watcher in Vue Components

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.

Description Data Computed Watcher
Store variables Store local variables Computed variables. Can be static, derived from other variables, or can be static functions Does not store variables - only watches them.
React to variable value changes Y Y Y
Cached? Y Y N/A
Scope Local to component Local 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> methods Y
this.myName
Y
this.myCalcName
N/A
Perform action when value changes N N Y
Consequence of a value change Change UI to react to change Change UI Perform action - local/vuex
Can change other variable values N Y Y

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

comments powered by Disqus