7

i am wondering what s the difference between a method declared in data, or a method declared in methods?

var app = new Vue({
  el: "#vue-app",
  data: {
    name: function() {
      console.log("Alex");
    }
  },
  methods: {
    name: function() {
      console.log("Alex");
    }
  }
});

1 Answer 1

6

tl;dr If all you have inside is a console.log("Alex"), they will work the same. But if you have a this inside them, they will differ greatly.


Firstly, Vue data objects are expected to be plain JavaScript objects, without methods. From the API docs:

The data object for the Vue instance. Vue will recursively convert its properties into getter/setters to make it “reactive”. The object must be plain: native objects such as browser API objects and prototype properties are ignored. A rule of thumb is that data should just be data - it is not recommended to observe objects with their own stateful behavior.

So, even if it worked, I'd declare them in methods to follow the POLA.

A crucial difference:

But, more importantly, there's a key factor: methods are bound to the Vue instance. Which means the this inside methods always point to the current Vue instance.

new Vue({
  el: '#app',
  data: {
    nameData: function() {
      console.log("nameData", this.otherMethod()) // doesn't work
    },
  },
  methods: {
    nameMethod: function() {
      console.log("nameMethod", this.otherMethod()); // works
    },
    otherMethod() {
      return "I am other method";
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <button @click="nameData">invoke nameData</button><br>
  <button @click="nameMethod">invoke nameMethod</button>
</div>

Yet another example:

new Vue({
  el: '#app',
  data: {
    id: 3,
    ids: [1,2,3,4],
    equalsIdData: function(i) {
      return this.id === i;
    },
  },
  methods: {
    equalsIdMethod: function(i) {
      return this.id === i;
    },
    yetAnotherMethod: function() {
      console.log('equalsIdMethod:', this.ids.filter(this.equalsIdMethod)); // filters correctly
      console.log('equalsIdData:',   this.ids.filter(this.equalsIdData)); // filters incorrectly
    },
  }
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
  <button @click="yetAnotherMethod">invoke yetAnotherMethod</button>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

"Whereas a method declared in a data property is only accessible when you reference that property directly.". Well, i can access that property(name) from data directily from otherMethod too, with the same this.name() .
Again, i understand the POLA factor, but for me is still working, if i use <button @click="nameData()">invoke nameData</button><br> : jsfiddle.net/Lgoq8qs3/3
Besides you having to add (), it works, but it is is accidental. Check this one: jsfiddle.net/acdcjunior/Lgoq8qs3/12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.