2
votes

I am trying to figure out when to call the methods property, versus when is best to call a computed property. It seems to me that computed is generally preferable since a method will respond anytime a property is called which accesses the DOM.

In the following code, the two buttons tracks a basic counter which increments by 1. The same output is passed to the DOM through a method and through a computed property. Every increment triggers both the computed and the methods properties as shown in the console.

<div id="content">
<!--counter control-->
  <button v-on:click="counter++">Increase Counter</button>
  <button v-on:click="counter--">Decrease Counter</button>

<!--counter output-->
  <p>{{counter}}</p>
  <p>{{ resultMethod() }}</p>
  <p>{{ resultComputed }}</p>
</div>


<script>
  new Vue({
    el: '#content',
    data: {
      counter: 0
    },
    computed: {
      resultComputed: function(){
        console.log("computed.result was run");
        return this.counter < 5 ? 'small_number' : 'LARGENUMBER';
      }
    },
    methods: {
      resultMethod: function(){
        console.log("methods.result was run");
        return this.counter < 5 ? 'small_number' : 'LARGENUMBER';
      }
    }
  })
</script>

Now if we add another couple data properties we can see that tracking them doesn't cause the method or the computed property to be triggered.

<!--new data options-->
  <button v-on:click="secondCounter++">Second Counter</button>
  <button v-on:click="formSubmit=true">Form Submit</button>

    //New Data Properties
      secondCounter: 0,
      formSubmit: false

Now displaying these data properties to the DOM shows first that the data is indeed being tracked correctly, and second these actions trigger the same methods property as our counter even though these variables are not related to this method.

  <p>{{secondCounter}}</p>
  <p>{{formSubmit}}</p>

Finally, if we create an entirely random and unrelated method and reference it in the DOM, this too will be called everytime any of our variables are changed from the DOM. I use the simple method as an example.

<h2>{{ unrelatedMethod() }}</h2>

unrelatedMethod: function(){
    console.log("We are now using another random method");
    var number = 2000;
    return number;
  }

So what exactly is happening here behind the scenes? Does Vue have to run every related property everytime the DOM is updataed? When would methods be a better choice over computed properties?

1

1 Answers

1
votes

In the first case, both the computed property and the method have to be called for slightly different reasons. First, updating counter triggers a re-render, because counter is referenced in the template. Likewise, resultComputed is triggered because counter changed. Finally because the template is being re-rendered, resultMethod is called because it is referenced in the template.

Lets take a part of your second case and add secondCounter as a property, a button that increments it, and add secondCounter to the template. In this case, when you increment secondCounter, because secondCounter is referenced in the template, a re-render is triggered. resultMethod will be called again because it is referenced in the template, but resultComputed is not triggered. resultComputed will only be re-calculated if counter changes.

Vue will only re-calculate computed properties when the data used inside their function changes.

Because you are referencing the resultMethod in the template, it will be called every time the Vue is re-rendered. The Vue has to be re-rendered whenever counter and secondCounter change because they are also referenced in the template. If you took counter out of the template, the Vue would still re-render because resultMethod depends on it and resultMethod is referenced in the template.