Petro Pavliuk
Petro Pavliuk

Reputation: 443

Call only one method from methods

On this example, I change the "name" via the method:

new Vue({
  el: '#exercise',
  data: {
    name: 'Petr',
  },
  methods: {
    random: function() {
      return Math.random();
    },
    changeName: function(event) {
      this.name = event.target.value;
    }
  }
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="exercise">
  <p>VueJS is pretty cool - {{ name }}</p>
  <p>{{ random() }}</p>
  <div>
    <input v-on:input="changeName" type="text">
  </div>
</div>

But each time I call the method changeName the other method (random) also is called.

Why?

Upvotes: 3

Views: 491

Answers (2)

acdcjunior
acdcjunior

Reputation: 135752

From Computed Properties - Computed Caching vs Methods:

In comparison, a method invocation will always run the function whenever a re-render happens.

And when does a re-render happen? When data changes.

And in your example data (i.e. name) changes whenever you type into the <input> (because it calls changeName).

Check the lifecycle diagram - more specifically, the "Mounted" red ball:

vue.js 2 lifecycle diagram

Check the demo below, so you see those lifecycle events are happening (and thus the re-rendering between them):

new Vue({
  el: '#exercise',
  data: {
    name: 'Petr',
  },
  beforeUpdate() {
    console.log('beforeUpdate executed');
  },
  updated() {
    console.log('updated executed');
  },
  methods: {
    random: function() {
      return Math.random();
    },
    changeName: function(event) {
      this.name = event.target.value;
    }
  }
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>

<div id="exercise">
  <p>VueJS is pretty cool - {{ name }}</p>
  <p>{{ random() }}</p>
  <div>
    <input v-on:input="changeName" type="text">
  </div>
</div>

Upvotes: 1

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85545

@acdcjunior explained it very well about this issue:

In comparison, a method invocation will always run the function whenever a re-render happens.

But what if you really want to bind the random method when you really want? Here's the solution:

Modified HTML

<div id="exercise">
  <p>VueJS is pretty cool - {{ name }}</p>
  <p>{{ randomNumber }}</p>
  <div>
    <input v-on:input="changeName" type="text">
    <input type="button" @click="random" value="Generate Random Number">
  </div>
</div>

In the preceding example, we are using data randomNumber. I have added a button that holds the random method to generate a random number when we click on it.

// modified data option:
data: {
  name: 'Petr',
  randomNumber: '' /* initialize randomNumber */
},
// modified random method
methods: {
  random: function() {
    /* Now, we return data randomNumber */
    return this.randomNumber = Math.random();
  },
  changeName: function(event) {
    this.name = event.target.value;
  }
},
created() {
  // we need to show random number when instance is created
  this.random();
}

What the heck is happening here? The method random should be invoked and the random number should also be generated, right?

No. The method random isn't invoked because we've not used this method anywhere ie. not bound random() in our template binding.

So, what it means is that, the method is only invoked (after re-render as being said) if there is the method hooked somewhere inside our template.

Upvotes: 0

Related Questions