Metodo vs calcolato in Vue


178

Qual è la differenza principale tra un metodo e un valore calcolato in Vue.js?

Sembrano uguali e intercambiabili.



1
@xDreamCoding La risposta che si collega capita di rispondere effettivamente a questa domanda, ma in nessun modo questa domanda è una duplicazione. Inoltre è più famoso.
Romain Vincent,

Fare riferimento alla documentazione che getta luce su questo argomento sotto la voce Proprietà calcolate vs metodi: vuejs.org/v2/guide/computed.html
Kshitij Dhyani

Risposte:


243

I valori e i metodi calcolati sono molto diversi in Vue e nella maggior parte dei casi non sono assolutamente intercambiabili.

Proprietà calcolata

Un nome più appropriato per un valore calcolato è una proprietà calcolata . Infatti, quando viene creata un'istanza di Vue, le proprietà calcolate vengono convertite in una proprietà di Vue con un getter e talvolta un setter. Fondamentalmente puoi pensare a un valore calcolato come un valore derivato che verrà automaticamente aggiornato ogni volta che viene aggiornato uno dei valori sottostanti utilizzati per calcolarlo. Non si chiama un computer e non accetta alcun parametro. Fai riferimento a una proprietà calcolata proprio come faresti con una proprietà di dati. Ecco il classico esempio dalla documentazione :

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

A cui si fa riferimento nel DOM in questo modo:

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

I valori calcolati sono molto utili per manipolare i dati esistenti su Vue. Ogni volta che desideri filtrare o trasformare i tuoi dati, in genere utilizzerai un valore calcolato a tale scopo.

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

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

I valori calcolati vengono anche memorizzati nella cache per evitare il calcolo ripetitivo di un valore che non deve essere ricalcolato quando non è cambiato (poiché potrebbe non essere presente in un ciclo, ad esempio).

Metodo

Un metodo è solo una funzione associata all'istanza Vue. Sarà valutato solo quando lo chiami esplicitamente. Come tutte le funzioni javascript accetta parametri e sarà rivalutato ogni volta che viene chiamato. I metodi sono utili nelle stesse situazioni qualsiasi funzione è utile.

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

La documentazione di Vue è davvero buona e facilmente accessibile. Lo consiglio.


1
se ci sono due ingressi da un utente come una conversione di temperatura da C a F e viceversa in cui entrambi gli ingressi possono determinare il valore dell'altro. Vedi albireo.ch/temperatureconverter e che due ingressi reagiscono automaticamente senza premere il pulsante di conversione. quale è il più adatto per utilizzare calcolati o metodi?
Bootstrap4

2
Con quella specifica interfaccia utente in cui con la relazione circolare tra gli input, andrei con i metodi. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert

2
@ Bootstrap4 Anche se qui ce n'è uno con un calcolo, ma è più complicato. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert

3
> Un metodo ... verrà valutato solo quando lo chiami esplicitamente. Non secondo questo video: youtube.com/watch?v=O14qJr5sKXo
Cameron Hudson

2
@CameronHudson Nell'esempio nel video, i metodi vengono valutati perché sono esplicitamente indicati nel modello . Ecco un esempio che dimostra la differenza . Si noti che i metodi vengono chiamati solo quando i dati cambiano se sono esplicitamente indicati nel modello.
Bert,

60

Quando @gleenk ha chiesto un esempio pratico per mettere in evidenza le differenze di cache e dipendenza tra metodi e proprietà calcolate, mostrerò un semplice 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;
        }
    }
});

Qui abbiamo 2 metodi e 2 proprietà calcolate che eseguono la stessa attività. I metodi addToAmethode addToBmethode le proprietà calcolate addToAcomputede addToBcomputedtutto metti +20 (cioè il agevalore) a uno ao b. Per quanto riguarda i metodi, vengono entrambi chiamati ogni volta che è stata eseguita un'azione su una delle proprietà elencate, anche se le dipendenze per un metodo specifico non sono cambiate. Per le proprietà calcolate, il codice viene eseguito solo quando una dipendenza è cambiata; ad esempio, uno dei valori di proprietà specifici che fa riferimento ad A o B si attiverà addToAcomputedo addToBcomputed, rispettivamente.

Il metodo e le descrizioni calcolate sembrano abbastanza simili, ma dato che @Abdullah Khan lo ha già specificato , non sono la stessa cosa ! Ora proviamo ad aggiungere un po 'di html per eseguire tutto insieme e vedere dov'è la differenza.

La demo del caso Method

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>

Il risultato spiegato

Quando faccio clic sul pulsante "Aggiungi ad A" , vengono chiamati tutti i metodi (vedere il risultato della schermata del registro della console sopra), addToBmethod()viene anche eseguito ma non ho premuto il pulsante "Aggiungi a B" ; il valore della proprietà che fa riferimento a B non è cambiato. Lo stesso comportamento si verifica se decidiamo di fare clic sul pulsante "Aggiungi a B" , perché entrambi i metodi verranno chiamati indipendentemente dalle modifiche della dipendenza. Secondo questo scenario, questa è una cattiva pratica perché stiamo eseguendo i metodi ogni volta, anche quando le dipendenze non sono cambiate. Questo richiede davvero risorse perché non esiste una cache per i valori delle proprietà che non sono stati modificati.

metodo metodo pulsante

La demo del caso della proprietà calcolata

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>

Il risultato spiegato

Quando faccio clic sul pulsante "Aggiungi ad A" , addToAcomputedviene chiamata solo la proprietà calcolata perché, come abbiamo già detto, le proprietà calcolate vengono eseguite solo quando una dipendenza è cambiata. E poiché non ho premuto il pulsante "Aggiungi a B" e il valore della proprietà age per B non è cambiato, non c'è motivo di chiamare ed eseguire la proprietà calcolata addToBcomputed. Quindi, in un certo senso, la proprietà calcolata mantiene lo stesso valore "invariato" per la proprietà B come una specie di cache. E in questa circostanza questo è considerato una buona pratica .

computerizzata pulsante calcolato


3
Perché tutti i metodi vengono eseguiti quando si preme 1 pulsante? Qual è la ragione / logica?
Bsienn,

1
@Bsienn è una buona domanda: la ragione è che sostanzialmente Vue non sa quale dei metodi debba essere eseguito a seconda di ciò che è stato aggiornato. E questo è il tipo di operazioni eseguite dalle proprietà calcolate, osservano le variabili che devono essere calcolate o ricalcolate e vengono eseguite solo quando necessario.
Giulio Bambini,

2
E quali sono i motivi per usare i metodi? Sembra che le proprietà calcolate siano semplicemente migliori (supponendo che stiamo parlando di metodi "get") ...
user3529607

5
@ user3529607 ma le proprietà calcolate non ricevono argomenti.
Rodion Golovushkin,

3
@ user3529607 Da quello che posso capire, i metodi possono essere utili durante il montaggio o la creazione dell'istanza di Vue. Lo stesso non si può fare con le proprietà calcolate. Inoltre, dobbiamo restituire il valore per le proprietà calcolate.
Dhaval Chheda,

13

Dal docs

Le proprietà ..computed sono memorizzate nella cache in base alle loro dipendenze. Una proprietà calcolata rivaluterà solo quando alcune delle sue dipendenze sono cambiate.

Se si desidera che i dati vengano memorizzati nella cache, utilizzare le proprietà calcolate se non si desidera che i dati vengano memorizzati nella cache, utilizzare le proprietà del metodo semplici.


1
Ciao, potresti scrivere un esempio utile per mostrare la differenza di uso pratico?
Davide De Maestri,

@gleenk Aggiungerò un esempio pratico per mostrarti questa differenza cache / dipendenze tra metodi e proprietà calcolate. Spero che lo apprezzerai.
Giulio Bambini,

Grazie @GiulioBambini
Davide De Maestri

7

Una delle differenze tra calcolato e metodo. Supponiamo di avere una funzione che restituirà il valore del contatore (il contatore è solo variabile). Vediamo come si comporta la funzione sia nel calcolo che nel metodo

Computerizzata

Alla prima esecuzione il codice all'interno della funzione verrà eseguito e vuejs memorizzerà il valore del contatore nella cache (per un accesso più veloce). Ma quando chiameremo di nuovo la funzione vuejs non eseguirà di nuovo il codice scritto all'interno di quella funzione. Prima controlla tutte le modifiche apportate al contatore o meno. Se vengono apportate modifiche, solo questa eseguirà nuovamente il codice che si trova all'interno di quella funzione. Se non sono state apportate modifiche al contatore, vuejs non eseguirà nuovamente la funzione. Restituirà semplicemente il risultato precedente dalla cache.

Metodo

Questo è proprio come un normale metodo nel javascript. Ogni volta che chiamiamo il metodo eseguirà sempre il codice all'interno della funzione indipendentemente dalle modifiche apportate al contatore.

Il metodo eseguirà sempre nuovamente il codice indipendentemente dalle modifiche nel codice. dove, come calcolato, eseguirà nuovamente il codice solo se uno dei suoi valori di dipendenza è cambiato. Altrimenti ci darà il risultato precedente dalla cache senza rieseguire


6

Ecco una ripartizione di questa domanda.

Quando usare i metodi

  • Per reagire ad alcuni eventi che si verificano nel DOM
  • Per chiamare una funzione quando succede qualcosa nel tuo componente.
  • È possibile chiamare un metodo da proprietà calcolate o watcher.

Quando utilizzare le proprietà calcolate

  • È necessario comporre nuovi dati da origini dati esistenti
  • Hai una variabile che usi nel tuo modello creata da una o più proprietà dei dati
  • Vuoi ridurre un nome di proprietà nidificato complicato a uno più leggibile e facile da usare (ma aggiornalo quando cambia la proprietà originale)
  • Devi fare riferimento a un valore dal modello. In questo caso, la creazione di una proprietà calcolata è la cosa migliore, perché è memorizzata nella cache.
  • È necessario ascoltare le modifiche di più di una proprietà di dati

2

Proprietà calcolate

Le proprietà calcolate sono anche chiamate valore calcolato. Significa che si aggiornano e possono essere modificati in qualsiasi momento. Inoltre, memorizza nella cache i dati fino a quando non cambia. Quando viene creata un'istanza di Vue, le proprietà calcolate vengono convertite in una proprietà.

Un'altra cosa che voglio condividere, non è possibile passare alcun parametro nelle proprietà calcolate, motivo per cui durante la chiamata a qualsiasi proprietà del computer non è necessaria la parentesi.

metodi

I metodi sono gli stessi della funzione e funzionano allo stesso modo. Inoltre, un metodo non fa nulla se non lo chiami. Inoltre, come tutte le funzioni javascript, accetta i parametri e verrà rivalutato ogni volta che viene chiamato. Successivamente, non possono memorizzare nella cache valori

Nel metodo di chiamata è presente la parentesi ed è possibile inviare uno o più parametri.


0

Ci siamo imbattuti nella stessa domanda. Per me è più chiaro in questo modo:

  1. Quando Vue.js vede v-on directiveseguito da un metodo, sa esattamente quale metodo chiamare e quando chiamarlo.
<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 */
  1. Quando un metodo viene chiamato senzav-on directive , verrà chiamato ogni volta che viene attivato un evento sulla pagina che aggiorna il DOM (o semplicemente deve eseguire nuovamente il rendering di una parte della pagina). Anche quando quel metodo non ha nulla a che fare con l'attivazione dell'evento.
<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.*/
  1. Una proprietà calcolata viene chiamata solo quando viene modificato un valore di proprietà a cui fa riferimento la thisparola nella sua definizione di funzione.
<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.  */

Il take away qui è che è meglio usare le computedproprietà nel caso in cui un metodo non venga chiamato con il v-on directive.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.