Método vs Computado no Vue

178

Qual é a principal diferença entre um método e um valor calculado no Vue.js?

Eles parecem iguais e intercambiáveis.

Bootstrap4
fonte
Talvez seja útil para você: vuejs.org/v2/guide/computed.html#Computed-Properties
DunDev
1
@xDreamCoding A resposta que você vincula de fato aborda essa questão, mas de maneira alguma essa questão é uma duplicata. Além disso, é mais famoso.
Romain Vincent
Consulte a documentação que esclarece esse tópico sob o título Propriedades computadas versus métodos: vuejs.org/v2/guide/computed.html
Kshitij Dhyani

Respostas:

243

Os valores e métodos computados são muito diferentes no Vue e definitivamente não são intercambiáveis ​​na maioria dos casos.

Propriedade computada

Um nome mais apropriado para um valor calculado é uma propriedade calculada . De fato, quando o Vue é instanciado, as propriedades calculadas são convertidas em uma propriedade do Vue com um getter e, às vezes, um setter. Basicamente, você pode pensar em um valor calculado como um valor derivado que será atualizado automaticamente sempre que um dos valores subjacentes usados ​​para calculá-lo for atualizado. Você não chama um computado e ele não aceita nenhum parâmetro. Você faz referência a uma propriedade computada como faria com uma propriedade de dados. Aqui está o exemplo clássico da documentação :

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

Que é referenciado no DOM assim:

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

Os valores calculados são muito valiosos para manipular dados existentes no seu Vue. Sempre que você deseja filtrar ou transformar seus dados, normalmente você usará um valor calculado para essa finalidade.

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

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

Os valores calculados também são armazenados em cache para evitar o cálculo repetitivo de um valor que não precisa ser recalculado quando não foi alterado (pois pode não estar em um loop, por exemplo).

Método

Um método é apenas uma função vinculada à instância do Vue. Ele só será avaliado quando você o chamar explicitamente. Como todas as funções javascript, ele aceita parâmetros e será reavaliado toda vez que for chamado. Os métodos são úteis nas mesmas situações em que qualquer função é útil.

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

A documentação do Vue é realmente boa e facilmente acessível. Eu recomendo.

Bert
fonte
1
se houver duas entradas de um usuário, como uma conversão de temperatura de c para f e vice-versa, em que ambas as entradas podem determinar o valor uma da outra. Veja albireo.ch/temperatureconverter e essas duas entradas reagem automaticamente sem pressionar o botão converter. qual é o melhor ajuste para usar métodos ou computados?
usar o seguinte
2
Com essa interface específica, onde com o relacionamento circular entre as entradas, eu usaria métodos. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert
2
@ Bootstrap4 Porém, aqui está um com um computador também, mas é mais complicado. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert
3
> Um método ... só será avaliado quando você o chamar explicitamente. Não de acordo com este vídeo: youtube.com/watch?v=O14qJr5sKXo
Cameron Hudson
2
@CameronHudson No exemplo do vídeo, os métodos são avaliados porque são explicitamente referenciados no modelo . Aqui está um exemplo que demonstra a diferença . Observe que os métodos são chamados apenas quando os dados mudam se forem explicitamente referenciados no modelo.
1144 Bert Bert
60

Como o @gleenk pediu um exemplo prático para evidenciar as diferenças de cache e dependência entre métodos e propriedades computadas, mostrarei um cenário simples:

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

Aqui temos 2 métodos e 2 propriedades calculadas que executam a mesma tarefa. Os métodos addToAmethode addToBmethode as propriedades computadas addToAcomputede addToBcomputedtudo add +20 (ou seja, o agevalor), quer aou b. Em relação aos métodos, ambos são chamados toda vez que uma ação é executada em qualquer uma das propriedades listadas, mesmo que as dependências de um método específico não tenham sido alteradas. Para as propriedades calculadas, o código é executado apenas quando uma dependência foi alterada; por exemplo, um dos valores específicos da propriedade que se refere a A ou B será acionado addToAcomputedou addToBcomputed, respectivamente.

O método e as descrições computadas parecem bastante semelhantes, mas como o @Abdullah Khan já o especificou , eles não são a mesma coisa ! Agora vamos tentar adicionar um pouco de html para executar tudo junto e ver onde está a diferença.

A demonstração de caso do 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>

O resultado explicado

Quando clico no botão "Adicionar a A" , todos os métodos são chamados (veja o resultado da tela de log do console acima), o addToBmethod()também é executado, mas não pressionei o botão "Adicionar a B" ; o valor da propriedade que se refere a B não foi alterado. O mesmo comportamento ocorre se decidirmos clicar no botão "Adicionar a B" , porque novamente os dois métodos serão chamados independentemente das alterações de dependência. De acordo com esse cenário, é uma prática ruim porque estamos executando os métodos sempre, mesmo quando as dependências não foram alteradas. Isso realmente consome recursos, porque não há um cache para os valores das propriedades que não foram alterados.

método método de botão

A demonstração do caso da propriedade 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>

O resultado explicado

Quando clico no botão "Adicionar a A" , apenas a propriedade computada addToAcomputedé chamada porque, como já dissemos, as propriedades computadas são executadas somente quando uma dependência foi alterada. E como eu não pressionei o botão "Add to B" e o valor da propriedade age para B não mudou, não há razão para chamar e executar a propriedade computada addToBcomputed. Portanto, em certo sentido, a propriedade computada mantém o valor "igual inalterado" para a propriedade B como uma espécie de cache. E, nessa circunstância, isso é considerado uma boa prática .

computado botão computado

Giulio Bambini
fonte
3
Por que todos os métodos são executados quando 1 botão é pressionado? Qual é o motivo / lógica?
Bsienn 23/02
1
@Bsienn, é uma boa pergunta: o motivo é que basicamente o Vue não sabe qual dos métodos precisa executar, dependendo do que foi atualizado. E esse é o tipo de operação que as propriedades calculadas realizam, elas observam as variáveis ​​que precisam ser calculadas ou recalculadas e só executam quando necessário.
Giulio Bambini 23/02
2
E quais são as razões para usar métodos? Parece que as propriedades calculadas são apenas melhores (assumindo que estamos a falar de métodos 'Get') ...
user3529607
5
@ user3529607 mas as propriedades calculadas não recebem argumentos.
Rodion Golovushkin
3
@ user3529607 Pelo que entendi, os métodos podem ser úteis ao montar ou criar a instância do vue. O mesmo não pode ser feito com propriedades calculadas. Além disso, temos que retornar o valor para as propriedades calculadas.
Dhaval Chheda
13

De docs

As propriedades ..computed são armazenadas em cache com base em suas dependências. Uma propriedade computada somente reavaliará quando algumas de suas dependências forem alteradas.

Se você deseja que os dados sejam armazenados em cache, use as propriedades Computadas, por outro lado, se você não deseja que os dados sejam armazenados em cache, use propriedades simples de Método.

Abdullah Khan
fonte
1
Olá, você poderia escrever um exemplo útil para mostrar a diferença de uso prático?
Davide De Maestri
@gleenk Vou adicionar um exemplo prático para mostrar essa diferença de cache / dependências entre métodos e propriedades calculadas. Espero que você goste.
Giulio Bambini 08/01
Obrigado @GiulioBambini
Davide De Maestri
7

Uma das diferenças entre computado e método. Suponha que tenhamos uma função que retornará o valor do contador (o contador é apenas variável). Vamos ver como a função se comporta no método computado e no método

Computado

No primeiro momento da execução, o código dentro da função será executado e o vuejs armazenará o valor do contador no cache (para acessar mais rapidamente). Porém, quando chamarmos novamente a função, vuejs não executará novamente o código escrito dentro dessa função. Ele primeiro verifica as alterações feitas no contador ou não. Se alguma alteração foi feita, somente ele executará novamente o código que está dentro dessa função. Se não houver alterações feitas no contador, o vuejs não executará novamente a função. Ele simplesmente retornará o resultado anterior do cache.

Método

É como um método normal no javascript. Sempre que chamamos o método, ele sempre executa o código dentro da função, independentemente das alterações feitas no contador.

O método sempre reexecutará o código, independentemente de alterações no código. onde, conforme calculado, reexecute o código somente se um dos valores de sua dependência for alterado. Caso contrário, ele nos fornecerá o resultado anterior do cache sem reexecutar

PALLAMOLLA SAI
fonte
6

Aqui está um detalhamento desta pergunta.

Quando usar métodos

  • Para reagir a algum evento acontecendo no DOM
  • Para chamar uma função quando algo acontecer no seu componente.
  • Você pode chamar um método a partir de propriedades computadas ou observadores.

Quando usar propriedades calculadas

  • Você precisa compor novos dados de fontes de dados existentes
  • Você tem uma variável usada em seu modelo criada a partir de uma ou mais propriedades de dados
  • Você deseja reduzir um nome de propriedade aninhado e complicado para um mais legível e fácil de usar (mas atualize-o quando a propriedade original for alterada)
  • Você precisa fazer referência a um valor do modelo. Nesse caso, criar uma propriedade computada é a melhor coisa, porque é armazenada em cache.
  • Você precisa ouvir alterações de mais de uma propriedade de dados
Diego Pereira
fonte
2

Propriedades computadas

As propriedades computadas também são chamadas de valor computado. Isso significa que eles são atualizados e podem ser alterados a qualquer momento. Além disso, ele armazena em cache os dados até que sejam alterados. Quando o Vue é instanciado, as propriedades calculadas são convertidas em uma propriedade.

Mais uma coisa que quero compartilhar: você não pode passar nenhum parâmetro nas propriedades calculadas, por isso, ao chamar qualquer propriedade do computador, nenhum parêntese é necessário.

Métodos

Os métodos são iguais à função e funcionam da mesma maneira. Além disso, um método não faz nada, a menos que você o chame. Além disso, como todas as funções javascript, ele aceita parâmetros e será reavaliado toda vez que for chamado. Depois disso, eles não podem armazenar valores em cache

No método chamado parênteses, existe e você pode enviar um ou mais parâmetros.

Rajat
fonte
0

Tropeçou na mesma pergunta. Para mim, é mais claro assim:

  1. Quando o Vue.js vê o v-on directiveseguido por um método, ele sabe exatamente qual método chamar e quando chamá-lo.
<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 um método é chamado sem o,v-on directive ele é chamado toda vez que um evento é acionado na página que atualiza o DOM (ou simplesmente precisa renderizar novamente uma parte da página). Mesmo quando esse método não tem nada a ver com o evento sendo acionado.
<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. Uma propriedade computada é chamada apenas quando um valor de propriedade é alterado, sendo referenciado pela thispalavra em sua definição de função.
<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.  */

A conclusão aqui é que é uma prática recomendada usar as computedpropriedades caso um método não esteja sendo chamado com o v-on directive.

DarkLite1
fonte