ChatGPT解决这个技术问题 Extra ChatGPT

Methods vs Computed in Vue

What is the main difference between a methods and a computed value in Vue.js?

They look the same and interchangeable.

@xDreamCoding The answer that you link happens to address this question indeed, but in no way is this question a duplicate. Plus it is more famous.
Refer to the documentation which throws some light on this topic under the heading of Computed properties vs methods : vuejs.org/v2/guide/computed.html

t
tony19

Computed values and methods are very different in Vue and are definitely not interchangeable in most cases.

Computed Property

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('')
  }
}

Which is referenced in the DOM like this:

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

Computed values are very valuable for manipulating data that exists on your Vue. Whenever you want to filter or transform your data, typically you will use a computed value for that purpose.

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

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

Computed values are also cached to avoid repetitively calculating a value that doesn't need to be re-calculated when it hasn't changed (as it might not be in a loop for example).

Method

A method is just a function bound to the Vue instance. It will only be evaluated when you explicitly call it. Like all javascript functions, it accepts parameters and will be re-evaluated every time it's called. Methods are useful in the same situations any function is useful.

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's documentation is really good and easily accessible. I recommend it.


if there are two inputs from a user like a temperature conversion from c to f and vice versa where both inputs can determine each others value . See albireo.ch/temperatureconverter and that two inputs react automatically without pressing convert button. which one is best fit to use computed or methods?
With that specific UI where with the circular relationship between the inputs, I would go with methods. codepen.io/Kradek/pen/gROQeB?editors=1010
@Bootstrap4 Though, here is one with a computed as well, but its more compllicated. codepen.io/Kradek/pen/gROQeB?editors=1010
> A method ... will only be evaluated when you explicitly call it. Not according to this video: youtube.com/watch?v=O14qJr5sKXo
@CameronHudson In the example in the video, the methods are evaluated because they are explicitly referenced in the template. Here is an example that demonstrates the difference. Note that methods are only called when the data changes if they are explicitly referenced in the template.
C
Community

As @gleenk asked for a practical example to make evident the cache and dependency differences between methods and computed properties, I'll show a simple scenario:

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.

The method and computed descriptions seem pretty similar, but as @Abdullah Khan has already specified it, they are not the same thing! Now let's try to add some html to execute everything together and see where the difference is.

The Method case demo

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; } } }); VueJS Methods - stackoverflow

Methods

Age + A = {{ addToAmethod() }}

Age + B = {{ addToBmethod() }}

The explained result

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.

https://i.stack.imgur.com/Fa8GT.png

The Computed property case demo

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; } } }); VueJS Computed properties - stackoverflow

Computed Properties

Age + A = {{ addToAcomputed }}

Age + B = {{ addToBcomputed }}

The explained result

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.

https://i.stack.imgur.com/j2aep.png


Why all methods gets executed when 1 button is pressed? Whats the reason / logic?
@Bsienn that's a good question: the reason is that basically Vue doesn't know which one of the methods needs to run depending on what has updated. And this is the kind of operations that computed properties do, they watch the variables that need to be computed or recalculated and they only run when needed.
And what are the reasons for using methods? It looks like computed properties are just better (assuming we are talking about 'get' methods)...
@user3529607 but computed properties don't receive arguments.
@user3529607 From what I can understand, methods can be useful while mounting or creating the instance of the vue. Same can't be done with computed properties. Also, we have to return the value for the computed properties.
D
Diego Caldeira

Here’s a breakdown of this question.

When to use methods

To react to some event happening in the DOM

To call a function when something happens in your component.

You can call a method from computed properties or watchers.

When to use computed properties

You need to compose new data from existing data sources

You have a variable you use in your template that’s built from one or more data properties

You want to reduce a complicated, nested property name to a more readable and easy to use one (but update it when the original property changes)

You need to reference a value from the template. In this case, creating a computed property is the best thing, because it’s cached.

You need to listen to changes of more than one data property


Clear and the best answer. Thanks Diego
Very clear and what I was looking for. Most of the answers explain why computed values are good, but I knew this. I was actually looking for why you would even want to use methods if computed are so good. This explains at least some of that.
t
tony19

From the docs

..computed properties are cached based on their dependencies. A computed property will only re-evaluate when some of its dependencies have changed.

If you want data to be cached use Computed properties on the other hand if you don't want data to be cached use simple Method properties.


Hi, could you write a useful example to show practical-use difference?
@gleenk I'll add a practical example for show you this cache/dependencies difference between methods and computed properties. I hope you'll appreciate it.
Thank you @GiulioBambini
P
Pallamolla Sai

One of difference between computed and method. Suppose we have a function which will return counter value.(counter is just variable). Let's look how function behaves in both computed and method

Computed

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.

Method

This is just like a normal method in the javascript. Whenever we call the method it will always execute the code inside the function irrespective of changes made to the counter.

Method will always reexecutes the code irrespective of changes in the code. where as computed will reexecute the code then only if one of it's dependency's values changed. Otherwise it will give us the previous result from the cache without reexecuting


R
Rajat

Computed Properties

Computed properties are called computed value as well. It means, they update and can be changed anytime. Also, it caches the data until it changes. When the Vue is instantiated, computed properties are converted into a property.

One more thing I want to share, You cannot pass any parameter in the computed properties that's why while calling any computer property no parenthesis required.

Methods

Methods are the same as function and work the same way. Besides, a method does nothing unless you call it. Also, like all javascript functions, it accepts parameters and will be re-evaluated every time it’s called. After that, they can’t cache values

In the method calling parenthesis is there and you can send one or more parameter in that.


So are you saying that computed values are calculated on init, whereas methods are calculated only when called?
D
DarkLite1

Stumbled upon the same question. To me it's more clear like this:

When Vue.js sees the v-on directive followed by a method, it knows exactly which method to call and when to call it.

<button v-on:click="clearMessage">Clear message</button> // @click
// method clearMessage is only called on a click on this button

<input v-model="message" @keyup.esc="clearMessage" @keyup.enter="alertMessage" />
/* The method clearMessage is only called on pressing the escape key
and the alertMessage method on pressing the enter key */

When a method is called without the v-on directive it will be called every time an event is triggered on the page that updates the DOM (or simply needs to re-render a part of the page). Even when that method has nothing to do with the event being triggered.

<p>Uppercase message: {{ messageUppercase() }}</p>
methods: {
   messageUppercase() {
      console.log("messageUpercase");
      return this.message.toUpperCase();
   }
}
/* The method `messageUppercase()` is called on every button click, mouse hover 
or other event that is defined on the page with the `v-on directive`. So every
time the page re-renders.*/

A Computed property is only called when a property value is changed that is being referenced by the this word in its function definition.

<p>Uppercase message: {{ messageUppercase }}</p> 
data() {
 return {
    message: "I love Vue.js"
   }
 },
computed: {
 messageUppercase() {
    console.log("messageUpercase");
    return this.message.toUpperCase();
 }
}
/* The computed property messageUppercase is only called when the propery message is
changed. Not on other events (clicks, mouse hovers,..) unless of course a specific 
event changes the value of message.  */

The take away here is that it's best practice to use the computed properties in case a method is not being called with the v-on directive.


V
Vinay Singh

As a simple way as per vueJs documentation:

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

While A computed property will only re-evaluate when some of its reactive dependencies have changed


B
Boussadjra Brahim

In vue composition API which comes with Vue 3 and which is available as plugin for vue 2, the methods and computed properties are a different syntax :

Examples :

computed :

It's a function that takes by default a getter callback as parameter and returns an immutable ref based on other property like ref, reactive or store state.

import {computed,ref} from 'vue'

export default{

setup(){
  const count=ref(0);
  
  const doubleCount=computed(()=>count.value*2) 

 return {count,doubleCount} //expose the properties to the template 
 }
}

Methods

Are plain javascript functions which behave in the same way in both Vue and vanilla js, they are exposed to template and used as event handlers, they shouldn't be used for rendering purposes which could lead to some issues like infinite rendering.

import {computed,ref} from 'vue'

export default{

setup(){
  const count=ref(0);
  
  const doubleCount=computed(()=>count.value*2) 
 
  function increment(){
   ref.value++
 }

 return {count,doubleCount,increment} //expose the properties/functions to the template 
 }
}

The difference :

computed :

It's evaluated as immutable property not as function

It observes another property and returns a property based on that one.

It cannot take a parameter.

It can be watched using a watch property

method :

Used to refactor a code inside computed/watcher property or other function

Used as event handler

It shouldn't be called inside a template to avoid rendering issues.


U
Utmost Creator

I will try to supplement the answers of other members. This example and explanations made me completely get the gist of computed properties. I hope after reading my post, you will be aware of it too.

If you need to change data, you must use methods. And when you need to change the presentation of existing data, you will use computed properties. As you practice both concepts, you will use them with ease. Here are some curial keys:

computed properties must always return a value; computed properties are only used for transforming data and not for changing it for our presentation layer | they should not alter or change the existing data.

As you have already read it or after you run my example code, you will see that only the values which are presented in the computed properties are bieng changed (either inside a method or by user input or by other means), the computed property will be recalculated and cached. But each time a method is called, it will be executed regardless of the result (e.g. in my example, when a value reaches the 0 value, the computed property is no longer recomputed)

In the example, there is a simple system; where you have:

own cash;

your cash in a bank account;

possibility to withdraw from your bank account;

possibility to lend some money from some person (with Infinity money).

new Vue({ el: '#app', data: { infinity: Infinity, value: 3, debt: -6, cash: 9, moneyInBank: 15, }, computed: { computedPropRemainingCashFundsIfPaid: function() { console.log('computedPropRemainingCashFundsIfPaid'); return this.debt + this.cash; }, computedPropRemainingTotalFunds: function() { console.log('computedPropRemainingTotalFunds'); return this.cash + this.moneyInBank + this.debt; } }, methods: { depositFunds: function(from, to, value, limit = false) { if (limit && (this[to] + value) >= 0) { // if you try to return greater value than you owe this[from] += this[to]; this[to] = 0; } else if (this[from] > value && this[from] - value >= 0) { // usual deposit this[to] += value; this[from] -= value; } else { // attempt to depost more than you have this[to] += this[from]; this[from] = 0; } }, repayADebt: function() { this.value = Math.abs(this.value); if (this.debt < 0) { this.depositFunds('cash', 'debt', this.value, true); } console.log('Attempt to repayADebt', this.value); }, lendAmount: function() { this.depositFunds('infinity', 'debt', -Math.abs(this.value)); console.log('Attempt to lendAmount', this.value); }, withdraw: function() { if (this.moneyInBank) { this.depositFunds('moneyInBank', 'cash', this.value); } console.log('Attempt to withdraw', this.value); } } }); * { box-sizing: border-box; padding: 0; margin: 0; overflow-wrap: break-word; } html { font-family: "Segoe UI", Tahoma, Geneva, Verdana; font-size: 62.5%; } body { margin: 0; font-size: 1.6rem; } #app { margin: 3rem auto; max-width: 50vw; padding: 1rem; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26); } label, input { margin-bottom: 0.5rem; display: block; width: 100%; } label { font-weight: bold; } ul { list-style: none; margin: 1rem 0; padding: 0; } li { margin: 1rem 0; padding: 1rem; border: 1px solid #ccc; } .grid { display: grid; grid: 1fr / 1fr min-content 1fr min-content; gap: 1rem; align-items: center; margin-bottom: 1rem; } .grid> :is(button, input) { height: 3rem; margin: 0; } .computed-property-desc { padding: 1rem; background-color: rgba(0, 0, 0, 0.3); text-align: justify; } A First App

Computed Properties Guide

Let's assume that you have {{ cash }}$; And you need to pay a debt={{ debt }}

Your bank account: {{ moneyInBank }}$

Your cash: {{ cash }}$

Your debt: {{ debt }}$

in amout of $

computedPropRemainingCashFundsIfPaid/
Available funds in case of debt repayment = {{ computedPropRemainingCashFundsIfPaid }}$

computedPropRemainingTotalFunds = {{ computedPropRemainingTotalFunds }}$

when you need to change data, you will use methods. And When you need to change the presentation of existing data, you will use computed properties. As you practice both concepts, it will become easier which one should you use. Very important notes: 1. it must always return a value; 2. computed properties are only used for transforming data and not for chaning it for our presentation layer | they should not alter or change the existing data


c
chase

Here's what the Vue3 documentation says - check it out for an example:

For the end result, the two approaches are indeed exactly the same. However, the difference is that computed properties are cached based on their reactive dependencies. A computed property will only re-evaluate when some of its reactive dependencies have changed. [...] In comparison, a method invocation will always run the function whenever a re-render happens.

Additional Links

Methods Computed Properties


m
mohammad

The difference between computed and methods is that when you define a function in computed, it executes the function from the beginning only if the answer changes, but methods executes the function from the beginning every time it is called.