Metoda vs obliczona w Vue

178

Jaka jest główna różnica między metodą a wartością obliczoną w Vue.js?

Wyglądają tak samo i są wymienne.

Bootstrap4
źródło
Może być pomocny dla Ciebie: vuejs.org/v2/guide/computed.html#Computed-Properties
DunDev
1
@xDreamCoding Odpowiedź, którą łączysz, rzeczywiście odpowiada na to pytanie, ale w żaden sposób nie jest to pytanie powtórzone. Poza tym jest bardziej znany.
Romain Vincent
Zapoznaj się z dokumentacją, która rzuca trochę światła na ten temat pod nagłówkiem Obliczone właściwości a metody: vuejs.org/v2/guide/computed.html
Kshitij Dhyani

Odpowiedzi:

242

Obliczone wartości i metody są bardzo różne w Vue i zdecydowanie nie można ich stosować zamiennie w większości przypadków.

Obliczona właściwość

Bardziej odpowiednią nazwą obliczanej wartości jest obliczona właściwość . W rzeczywistości, gdy tworzona jest instancja Vue, obliczone właściwości są konwertowane na właściwość Vue za pomocą metody pobierającej, a czasem ustawiającej. Zasadniczo można myśleć o wartości obliczonej jako o wartości pochodnej, która będzie automatycznie aktualizowana za każdym razem, gdy zaktualizowana zostanie jedna z bazowych wartości używanych do jej obliczenia. Nie wywołujesz obliczonego i nie akceptuje żadnych parametrów. Odwołujesz się do obliczonej właściwości, tak jak do właściwości danych. Oto klasyczny przykład z dokumentacji :

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

Do którego odwołuje się DOM w ten sposób:

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

Obliczone wartości są bardzo cenne przy manipulowaniu danymi istniejącymi w Twoim Vue. Ilekroć chcesz przefiltrować lub przekształcić dane, zazwyczaj będziesz używać do tego celu wartości obliczonej.

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

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

Obliczone wartości są również zapisywane w pamięci podręcznej, aby uniknąć wielokrotnego obliczania wartości, która nie musi być ponownie obliczana, gdy nie uległa zmianie (na przykład może nie znajdować się w pętli).

metoda

Metoda to po prostu funkcja powiązana z instancją Vue. Zostanie on oceniony tylko wtedy, gdy wyraźnie go nazwiesz. Podobnie jak wszystkie funkcje javascript akceptuje parametry i będzie ponownie oceniana za każdym razem, gdy zostanie wywołana. Metody są przydatne w tych samych sytuacjach, w których każda funkcja jest przydatna.

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

Dokumentacja Vue jest naprawdę dobra i łatwo dostępna. Polecam to.

Bert
źródło
1
jeśli użytkownik ma dwa wejścia, takie jak konwersja temperatury z c na f i odwrotnie, gdzie oba wejścia mogą określać nawzajem wartość. Zobacz albireo.ch/temperatureconverter i sprawdź, czy dwa wejścia reagują automatycznie bez naciskania przycisku konwersji. który z nich najlepiej nadaje się do korzystania z metod komputerowych lub metod?
Bootstrap4
2
W tym konkretnym interfejsie użytkownika, w którym z cykliczną relacją między danymi wejściowymi, wybrałbym metody. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert
2
@ Bootstrap4 Chociaż, tutaj jest również jeden z obliczonym, ale jest bardziej skomplikowany. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert
3
> Metoda ... zostanie oceniona tylko wtedy, gdy ją jawnie wywołasz. Nie według tego filmu: youtube.com/watch?v=O14qJr5sKXo
Cameron Hudson.
2
@CameronHudson W przykładzie w filmie metody są oceniane, ponieważ są wyraźnie przywoływane w szablonie . Oto przykład, który pokazuje różnicę . Należy zauważyć, że metody są wywoływane tylko wtedy, gdy dane ulegają zmianie, jeśli są jawnie przywoływane w szablonie.
Bert,
60

Ponieważ @gleenk poprosił o praktyczny przykład pokazujący różnice w pamięci podręcznej i zależnościach między metodami i obliczonymi właściwościami, pokażę prosty scenariusz:

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;
        }
    }
});

Tutaj mamy 2 metody i 2 obliczone właściwości, które wykonują to samo zadanie. Metody addToAmethodi addToBmethodoraz obliczone właściwości addToAcomputedi addToBcomputedwszystkie add +20 (czyli agewartość) albo aalbo b. W odniesieniu do metod, są one zarówno nazywany każdym razem, gdy czynność została wykonana na dowolny z wymienionych właściwości, nawet jeśli Zależności dla konkretnej metodzie jeden nie uległy zmianie. W przypadku obliczonych właściwości kod jest wykonywany tylko wtedy, gdy zmieniła się zależność; na przykład jedna z określonych wartości właściwości, które odnoszą się do A lub B, wyzwoli odpowiednio addToAcomputedlub addToBcomputed.

Metoda i obliczone opisy wydają się dość podobne, ale ponieważ @Abdullah Khan już je określił , nie są tym samym ! Teraz spróbujmy dodać trochę kodu HTML, aby wykonać wszystko razem i zobaczyć, gdzie jest różnica.

Demo przypadku metody

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>

Wyjaśniony wynik

Kiedy klikam przycisk „Dodaj do A” , wywoływane są wszystkie metody (zobacz powyższy wynik na ekranie dziennika konsoli), addToBmethod()jest również wykonywany, ale nie nacisnąłem przycisku „Dodaj do B” ; wartość właściwości odnosząca się do B nie uległa zmianie. To samo zachowanie pojawia się, gdy zdecydujemy się kliknąć przycisk „Dodaj do B” , ponieważ ponownie obie metody zostaną wywołane niezależnie od zmian zależności. Zgodnie z tym scenariuszem jest to zła praktyka, ponieważ za każdym razem wykonujemy te metody, nawet jeśli zależności nie uległy zmianie. To naprawdę pochłania zasoby, ponieważ nie ma pamięci podręcznej dla wartości właściwości, które nie uległy zmianie.

metoda metoda przycisku

Prezentacja przypadku właściwości obliczonej

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>

Wyjaśniony wynik

Kiedy klikam przycisk „Dodaj do A” , addToAcomputedwywoływana jest tylko obliczona właściwość, ponieważ, jak już powiedzieliśmy, obliczone właściwości są wykonywane tylko wtedy, gdy zmieniła się zależność. A ponieważ nie nacisnąłem przycisku „Dodaj do B” i wartość właściwości wieku dla B nie uległa zmianie, nie ma powodu, aby wywoływać i wykonywać obliczoną właściwość addToBcomputed. Zatem, w pewnym sensie, obliczona właściwość zachowuje „tę samą niezmienioną” wartość właściwości B jak rodzaj pamięci podręcznej. W tej sytuacji należy to uznać za dobrą praktykę .

obliczone przycisk obliczony

Giulio Bambini
źródło
3
Dlaczego wszystkie metody są wykonywane po naciśnięciu przycisku 1? Jaki jest powód / logika?
Bsienn
1
@Bsienn to dobre pytanie: powód jest taki, że Vue w zasadzie nie wie, która z metod musi zostać uruchomiona w zależności od tego, co zostało zaktualizowane. I to jest rodzaj operacji, które robią obliczone właściwości, obserwują zmienne, które muszą być obliczone lub ponownie obliczone, i są uruchamiane tylko wtedy, gdy są potrzebne.
Giulio Bambini
2
A jakie są powody stosowania metod? Wygląda na to, że obliczone właściwości są po prostu lepsze (zakładając, że mówimy o metodach „get”) ...
user3529607
5
@ user3529607, ale obliczone właściwości nie otrzymują argumentów.
Rodion Golovushkin
3
@ user3529607 Z tego, co rozumiem, metody mogą być przydatne podczas montowania lub tworzenia instancji vue. Tego samego nie można zrobić z obliczonymi właściwościami. Musimy również zwrócić wartość obliczonych właściwości.
Dhaval Chheda
13

Z docs

Właściwości ..computed są buforowane na podstawie ich zależności. Obliczona właściwość zostanie ponownie oszacowana tylko wtedy, gdy niektóre z jej zależności ulegną zmianie.

Jeśli chcesz, aby dane były buforowane, użyj właściwości obliczonych, z drugiej strony, jeśli nie chcesz, aby dane były buforowane, użyj prostych właściwości metody.

Abdullah Khan
źródło
1
Cześć, czy mógłbyś napisać przydatny przykład pokazujący różnicę w praktycznym zastosowaniu?
Davide De Maestri,
@gleenk Dodam praktyczny przykład, aby pokazać różnicę w pamięci podręcznej / zależnościach między metodami i obliczonymi właściwościami. Mam nadzieję, że to docenisz.
Giulio Bambini
Dziękuję @GiulioBambini
Davide De Maestri
7

Jedna z różnic między wyliczonymi a metodą. Załóżmy, że mamy funkcję, która zwraca wartość licznika (licznik jest po prostu zmienną). Spójrzmy, jak zachowuje się funkcja zarówno w przypadku metody obliczeniowej, jak i metody

Obliczone

Przy pierwszym wykonaniu kod wewnątrz funkcji zostanie wykonany, a vuejs zapisze wartość licznika w pamięci podręcznej (w celu szybszego dostępu). Ale kiedy ponownie wywołasz funkcję vuejs, nie wykona ponownie kodu zapisanego w tej funkcji. Najpierw sprawdza wszelkie zmiany wprowadzone w liczniku, czy nie. Jeśli wprowadzono jakiekolwiek zmiany, tylko wtedy ponownie wykona kod, który jest wewnątrz tej funkcji. Jeśli nie ma żadnych zmian w liczniku, vuejs nie będzie ponownie wykonywał funkcji. Po prostu zwróci poprzedni wynik z pamięci podręcznej.

metoda

Jest to normalna metoda w javascript. Za każdym razem, gdy wywołujemy metodę, zawsze wykona kod wewnątrz funkcji, niezależnie od zmian wprowadzonych w liczniku.

Metoda zawsze wykonuje ponownie kod niezależnie od zmian w kodzie. gdzie zgodnie z obliczeniami ponownie wykona kod tylko wtedy, gdy zmieni się jedna z wartości jego zależności. W przeciwnym razie da nam poprzedni wynik z pamięci podręcznej bez ponownego wykonywania

PALLAMOLLA SAI
źródło
6

Oto podział tego pytania.

Kiedy używać metod

  • Aby zareagować na jakieś zdarzenie w DOM
  • Aby wywołać funkcję, gdy coś się stanie w twoim komponencie.
  • Możesz wywołać metodę z obliczonych właściwości lub obserwatorów.

Kiedy używać obliczonych właściwości

  • Musisz utworzyć nowe dane z istniejących źródeł danych
  • Masz zmienną, której używasz w szablonie, która jest zbudowana na podstawie co najmniej jednej właściwości danych
  • Chcesz zredukować skomplikowaną, zagnieżdżoną nazwę właściwości do bardziej czytelnej i łatwej w użyciu (ale zaktualizuj ją, gdy oryginalna właściwość się zmieni)
  • Musisz odwołać się do wartości z szablonu. W tym przypadku utworzenie obliczonej właściwości jest najlepszą rzeczą, ponieważ jest ona buforowana.
  • Musisz nasłuchiwać zmian więcej niż jednej właściwości danych
Diego Pereira
źródło
2

Obliczone właściwości

Obliczone właściwości są również nazywane wartością obliczoną. Oznacza to, że aktualizują się i można je zmienić w dowolnym momencie. Ponadto buforuje dane, dopóki się nie zmienią. Po utworzeniu wystąpienia Vue obliczone właściwości są konwertowane na właściwość.

Jeszcze jedna rzecz, którą chcę się podzielić, nie możesz przekazać żadnego parametru w obliczonych właściwościach, dlatego podczas wywoływania dowolnej właściwości komputera nie jest wymagany nawias.

Metody

Metody są takie same jak funkcje i działają w ten sam sposób. Poza tym metoda nic nie robi, chyba że ją nazwiesz. Ponadto, podobnie jak wszystkie funkcje javascript, akceptuje parametry i będzie ponownie oceniana za każdym razem, gdy zostanie wywołana. Po tym nie mogą buforować wartości

W metodzie wywołującej nawias jest tam i możesz wysłać jeden lub więcej parametrów.

Rajat
źródło
0

Natknąłem się na to samo pytanie. Dla mnie jest to bardziej jasne:

  1. Kiedy Vue.js widzi, v-on directivepo którym następuje metoda, wie dokładnie, którą metodę i kiedy wywołać.
<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. Gdy metoda jest wywoływana bezv-on directive niej, będzie wywoływana za każdym razem, gdy na stronie zostanie wyzwolone zdarzenie, które aktualizuje DOM (lub po prostu wymaga ponownego renderowania części strony). Nawet jeśli ta metoda nie ma nic wspólnego z wyzwalanym zdarzeniem.
<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. Właściwość Computed jest wywoływana tylko wtedy, gdy wartość właściwości jest zmieniana, do której odwołuje się thissłowo w definicji funkcji.
<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.  */

Na wynos jest to, że najlepszą praktyką jest użycie computedwłaściwości w przypadku, gdy metoda nie jest wywoływana z rozszerzeniem v-on directive.

DarkLite1
źródło