Vue.js中方法和计算值的主要区别是什么?

在我看来,它们是一样的,是可以互换的。


当前回答

computed和methods之间的区别在于,当你在computed中定义一个函数时,它只在答案改变时才从头执行该函数,而methods在每次调用时都从头执行该函数。

其他回答

Vue中的计算值和方法非常不同,在大多数情况下肯定是不可互换的。

计算属性

A more appropriate name for a computed value is a computed property. In fact, when the Vue is instantiated, computed properties are converted into a property of the Vue with a getter and sometimes a setter. Basically you can think of a computed value as a derived value that will be automatically updated whenever one of the underlying values used to calculate it is updated. You don't call a computed and it doesn't accept any parameters. You reference a computed property just like you would a data property. Here's the classic example from the documentation:

computed: {
  // a computed getter
  reversedMessage: function () {
    // `this` points to the vm instance
    return this.message.split('').reverse().join('')
  }
}

它在DOM中是这样引用的:

<p>Computed reversed message: "{{ reversedMessage }}"</p>

计算值对于操作Vue上存在的数据非常有价值。每当您想要过滤或转换数据时,通常都会使用计算值来实现此目的。

data:{
    names: ["Bob", "Billy", "Mary", "Jane"]
},
computed:{
    startsWithB(){
        return this.names.filter(n => n.startsWith("B"))
    }
}

<p v-for="name in startsWithB">{{name}}</p>

计算值也会被缓存,以避免重复计算一个没有改变时不需要重新计算的值(例如,因为它可能不在循环中)。

方法

方法只是绑定到Vue实例的函数。它只在显式调用时才会被求值。像所有的javascript函数一样,它接受参数,并且每次被调用时都会被重新求值。方法在同样的情况下也很有用,任何函数都有用。

data:{
    names: ["Bob", "Billy", "Mary", "Jane"]
},
computed:{
    startsWithB(){
        return this.startsWithChar("B")
    },
    startsWithM(){
        return this.startsWithChar("M")
    }
},
methods:{
    startsWithChar(whichChar){
        return this.names.filter(n => n.startsWith(whichChar))
    }
}

Vue的文档非常好,而且易于访问。我推荐它。

来自文档

..计算属性是基于它们的依赖项缓存的。计算属性只有在其某些依赖项发生更改时才会重新计算。

如果您希望缓存数据,请使用Computed属性,另一方面,如果您不想缓存数据,请使用简单的Method属性。

computed和methods之间的区别在于,当你在computed中定义一个函数时,它只在答案改变时才从头执行该函数,而methods在每次调用时都从头执行该函数。

@gleenk需要一个实际的例子来说明方法和计算属性之间的缓存和依赖关系的差异,我将展示一个简单的场景:

app.js

new Vue({
    el: '#vue-app',
    data: {
        a: 0,
        b: 0,
        age: 20
    },
    methods: {
        addToAmethod: function(){
            console.log('addToAmethod');
            return this.a + this.age;
        },
        addToBmethod: function(){
            console.log('addToBmethod');
            return this.b + this.age;
        }
    },
    computed: {
        addToAcomputed: function(){
            console.log('addToAcomputed');
            return this.a + this.age;
        },
        addToBcomputed: function(){
            console.log('addToBcomputed');
            return this.b + this.age;
        }
    }
});

Here we have 2 methods and 2 computed properties that perform the same task. The methods addToAmethod & addToBmethod and the computed properties addToAcomputed & addToBcomputed all add +20 (i.e. the age value) to either a or b. Regarding the methods, they are both called every time an action has been performed on any of the listed properties, even if the dependencies for one specific method have not changed. For the computed properties, the code is executed only when a dependency has changed; for example, one of the specific property values that refers to A or B will trigger addToAcomputed or addToBcomputed, respectively.

方法和计算描述看起来非常相似,但正如@Abdullah Khan已经指定的那样,它们不是一回事!现在让我们尝试添加一些html来一起执行所有内容,看看有什么不同。

方法案例演示

new Vue({ el: '#vue-app', data: { a: 0, b: 0, age: 20 }, methods: { addToAmethod: function(){ console.log('addToAmethod'); return this.a + this.age; }, addToBmethod: function(){ console.log('addToBmethod'); return this.b + this.age; } } }); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>VueJS Methods - stackoverflow</title> <link href="style.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script> </head> <body> <div id="vue-app"> <h1>Methods</h1> <button v-on:click="a++">Add to A</button> <button v-on:click="b++">Add to B</button> <p>Age + A = {{ addToAmethod() }}</p> <p>Age + B = {{ addToBmethod() }}</p> </div> </body> <script src="app.js"></script> </html>

解释结果

When I click on the button "Add to A", all the methods are called (see the console log screen result above), the addToBmethod() is also executed but I didn't press the "Add to B" button; the property value that refers to B has not changed. The same behaviour comes if we decide to click the button "Add to B", because again both the methods will be called independently of dependency changes. According to this scenario this is bad practice because we are executing the methods every time, even when dependencies have not changed. This is really resource consuming because there is not a cache for property values that have not changed.

Computed属性案例演示

new Vue({ el: '#vue-app', data: { a: 0, b: 0, age: 20 }, computed: { addToAcomputed: function(){ console.log('addToAcomputed'); return this.a + this.age; }, addToBcomputed: function(){ console.log('addToBcomputed'); return this.b + this.age; } } }); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>VueJS Computed properties - stackoverflow</title> <link href="style.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script> </head> <body> <div id="vue-app"> <h1>Computed Properties</h1> <button v-on:click="a++">Add to A</button> <button v-on:click="b++">Add to B</button> <p>Age + A = {{ addToAcomputed }}</p> <p>Age + B = {{ addToBcomputed }}</p> </div> </body> <script src="app.js"></script> </html>

解释结果

When I click on the button "Add to A", only the computed property addToAcomputed is called because, as we already said, the computed properties are executed only when a dependency has changed. And since I didn't press the button "Add to B" and the age property value for B has not changed, there is no reason to call and execute the computed property addToBcomputed. So, in a certain sense, the computed property is maintaining the "same unchanged" value for the B property like a kind of cache. And in this circumstance this is consider good practice.

计算与方法的区别之一。假设我们有一个返回计数器值的函数。(counter只是变量)。让我们看看函数在计算和方法中的行为

计算

At first time of execution the code inside the function will be executed and vuejs will store the counter value in cache(for accessing faster). But when we are again calling the function vuejs will not again execute the code written inside of that function. It first checks any changes made to the counter or not. If any changes made then only it will re-execute the code which is inside that function. If there are no changes made to the counter vuejs will not again execute the function. It will simply return the previous result from the cache.

方法

这就像javascript中的一个普通方法。无论何时调用该方法,它都将始终执行函数内部的代码,而不管对计数器做了什么更改。

方法将始终重新执行代码,而不考虑代码中的更改。其中as computed将重新执行代码,然后只有当它的一个依赖项的值改变了。否则,它将在不重新执行的情况下,向我们提供之前缓存的结果