Método vs Computado en Vue

178

¿Cuál es la principal diferencia entre un método y un valor calculado en Vue.js?

Se ven iguales e intercambiables.

Bootstrap4
fuente
Quizás sea útil para usted: vuejs.org/v2/guide/computed.html#Computed-Properties
DunDev
1
@xDreamCoding La respuesta que usted vincula sucede a esta pregunta, pero de ninguna manera es una pregunta duplicada. Además es más famoso.
Romain Vincent
Consulte la documentación que arroja algo de luz sobre este tema bajo el título de Propiedades computadas versus métodos: vuejs.org/v2/guide/computed.html
Kshitij Dhyani

Respuestas:

243

Los valores y métodos calculados son muy diferentes en Vue y definitivamente no son intercambiables en la mayoría de los casos.

Propiedad calculada

Un nombre más apropiado para un valor calculado es una propiedad calculada . De hecho, cuando se instancia la Vue, las propiedades calculadas se convierten en una propiedad de la Vue con un getter y, a veces, un setter. Básicamente, puede pensar en un valor calculado como un valor derivado que se actualizará automáticamente cada vez que se actualice uno de los valores subyacentes utilizados para calcularlo. No llama a un cómputo y no acepta ningún parámetro. Hace referencia a una propiedad calculada tal como lo haría con una propiedad de datos. Aquí está el ejemplo clásico de la documentación :

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

Que se hace referencia en el DOM así:

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

Los valores calculados son muy valiosos para manipular los datos que existen en su Vue. Siempre que desee filtrar o transformar sus datos, normalmente utilizará un valor calculado para ese propósito.

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

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

Los valores calculados también se almacenan en caché para evitar el cálculo repetitivo de un valor que no necesita ser recalculado cuando no ha cambiado (ya que podría no estar en un bucle, por ejemplo).

Método

Un método es solo una función vinculada a la instancia de Vue. Solo se evaluará cuando lo llame explícitamente. Como todas las funciones de JavaScript, acepta parámetros y será reevaluado cada vez que se llame. Los métodos son útiles en las mismas situaciones, cualquier función es ú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))
    }
}

La documentación de Vue es realmente buena y de fácil acceso. Lo recomiendo.

Bert
fuente
1
si hay dos entradas de un usuario, como una conversión de temperatura de c a f y viceversa, donde ambas entradas pueden determinar el valor del otro. Vea albireo.ch/temperatureconverter y que dos entradas reaccionan automáticamente sin presionar el botón de conversión. ¿Cuál es el más adecuado para usar métodos o computados?
Bootstrap4
2
Con esa interfaz de usuario específica donde con la relación circular entre las entradas, iría con métodos. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert
2
@ Bootstrap4 Sin embargo, aquí hay uno con un cálculo, pero es más complicado. codepen.io/Kradek/pen/gROQeB?editors=1010
Bert
3
> Un método ... solo se evaluará cuando lo llame explícitamente. No según este video: youtube.com/watch?v=O14qJr5sKXo
Cameron Hudson
2
@CameronHudson En el ejemplo en el video, los métodos se evalúan porque se hace referencia explícita en la plantilla . Aquí hay un ejemplo que demuestra la diferencia . Tenga en cuenta que los métodos solo se invocan cuando los datos cambian si se hace referencia explícita en la plantilla.
Bert
60

Cuando @gleenk solicitó un ejemplo práctico para hacer evidentes las diferencias de caché y dependencia entre los métodos y las propiedades calculadas, mostraré un escenario simple:

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

Aquí tenemos 2 métodos y 2 propiedades calculadas que realizan la misma tarea. Los métodos addToAmethod& addToBmethody las propiedades calculadas addToAcomputed& addToBcomputedtodos agregan +20 (es decir, el agevalor) a cualquiera ao b. Con respecto a los métodos, ambos se llaman cada vez que se realiza una acción en cualquiera de las propiedades enumeradas, incluso si las dependencias de un método específico no han cambiado. Para las propiedades calculadas, el código se ejecuta solo cuando una dependencia ha cambiado; por ejemplo, uno de los valores de propiedad específicos que se refieren a A o B se activará addToAcomputedo addToBcomputed, respectivamente.

El método y las descripciones calculadas parecen bastante similares, pero como @Abdullah Khan ya lo ha especificado , ¡ no son lo mismo ! Ahora intentemos agregar algunos html para ejecutar todo junto y ver dónde está la diferencia.

El método de demostración de casos

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>

El resultado explicado

Cuando hago clic en el botón "Agregar a A" , todos los métodos se llaman (vea el resultado de la pantalla de registro de la consola arriba), addToBmethod()también se ejecuta pero no presioné el botón "Agregar a B" ; El valor de la propiedad que se refiere a B no ha cambiado. El mismo comportamiento se produce si decidimos hacer clic en el botón "Agregar a B" , porque nuevamente los dos métodos se llamarán independientemente de los cambios de dependencia. Según este escenario, esta es una mala práctica porque estamos ejecutando los métodos cada vez, incluso cuando las dependencias no han cambiado. Esto realmente consume muchos recursos porque no hay un caché para los valores de propiedad que no han cambiado.

método método de botón

La demostración del caso de propiedad calculada

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>

El resultado explicado

Cuando hago clic en el botón "Agregar a A" , solo addToAcomputedse llama a la propiedad calculada porque, como ya dijimos, las propiedades calculadas se ejecutan solo cuando una dependencia ha cambiado. Y como no presioné el botón "Agregar a B" y el valor de propiedad de edad para B no ha cambiado, no hay razón para llamar y ejecutar la propiedad calculada addToBcomputed. Entonces, en cierto sentido, la propiedad calculada mantiene el "mismo valor sin cambios" para la propiedad B como una especie de caché. Y en esta circunstancia esto se considera una buena práctica .

calculado botón calculado

Giulio Bambini
fuente
3
¿Por qué todos los métodos se ejecutan cuando se presiona 1 botón? ¿Cuál es la razón / lógica?
Bsienn
1
@Bsienn esa es una buena pregunta: la razón es que básicamente Vue no sabe cuál de los métodos debe ejecutarse según lo que se haya actualizado. Y este es el tipo de operaciones que realizan las propiedades calculadas, observan las variables que deben calcularse o recalcularse y solo se ejecutan cuando es necesario.
Giulio Bambini
2
¿Y cuáles son las razones para usar métodos? Parece que las propiedades calculadas son simplemente mejores (suponiendo que estamos hablando de métodos 'get') ...
user3529607
55
@ user3529607 pero las propiedades calculadas no reciben argumentos.
Rodion Golovushkin,
3
@ user3529607 Por lo que puedo entender, los métodos pueden ser útiles al montar o crear la instancia de la vue. No se puede hacer lo mismo con las propiedades calculadas. Además, tenemos que devolver el valor de las propiedades calculadas.
Dhaval Chheda
13

Desde el docs

Las propiedades .computed se almacenan en caché en función de sus dependencias. Una propiedad calculada solo se reevaluará cuando algunas de sus dependencias hayan cambiado.

Si desea que los datos se almacenen en caché, utilice las propiedades calculadas, por otro lado, si no desea que los datos se almacenen en caché, utilice propiedades de método simples.

Abdullah Khan
fuente
1
Hola, ¿podrías escribir un ejemplo útil para mostrar la diferencia de uso práctico?
Davide De Maestri
@gleenk Agregaré un ejemplo práctico para mostrarle esta diferencia de caché / dependencias entre métodos y propiedades calculadas. Espero que lo aprecies.
Giulio Bambini
Gracias @GiulioBambini
Davide De Maestri
7

Uno de diferencia entre computado y método. Supongamos que tenemos una función que devolverá el valor del contador (el contador es solo variable). Echemos un vistazo cómo se comporta la función en ambas calculan y método

Calculada

En el primer momento de ejecución, el código dentro de la función se ejecutará y vuejs almacenará el valor del contador en la memoria caché (para acceder más rápido). Pero cuando volvemos a llamar a la función vuejs no volverá a ejecutar el código escrito dentro de esa función. Primero verifica los cambios realizados en el mostrador o no. Si se realiza algún cambio, solo volverá a ejecutar el código que está dentro de esa función. Si no se realizan cambios en el contador, vuejs no volverá a ejecutar la función. Simplemente devolverá el resultado anterior del caché.

Método

Esto es como un método normal en javascript. Siempre que llamemos al método, siempre ejecutará el código dentro de la función, independientemente de los cambios realizados en el contador.

El método siempre volverá a ejecutar el código independientemente de los cambios en el código. donde, tal como se calculó, volverá a ejecutar el código, entonces solo si uno de sus valores de dependencia ha cambiado. De lo contrario, nos dará el resultado anterior del caché sin volver a ejecutar

PALLAMOLLA SAI
fuente
6

Aquí hay un desglose de esta pregunta.

Cuando usar métodos

  • Para reaccionar ante algún evento que ocurra en el DOM
  • Llamar a una función cuando algo sucede en su componente.
  • Puede llamar a un método desde propiedades calculadas o observadores.

Cuándo usar propiedades calculadas

  • Necesita componer datos nuevos de fuentes de datos existentes
  • Tiene una variable que usa en su plantilla que está construida a partir de una o más propiedades de datos
  • Desea reducir un nombre de propiedad anidado complicado a uno más fácil de leer (pero actualícelo cuando cambie la propiedad original)
  • Debe hacer referencia a un valor de la plantilla. En este caso, crear una propiedad calculada es lo mejor, porque está en caché.
  • Debe escuchar los cambios de más de una propiedad de datos.
Diego Pereira
fuente
2

Propiedades calculadas

Las propiedades calculadas también se denominan valor calculado. Significa que se actualizan y se pueden cambiar en cualquier momento. Además, almacena en caché los datos hasta que cambie. Cuando se instancia la Vue, las propiedades calculadas se convierten en una propiedad.

Una cosa más que quiero compartir, no puede pasar ningún parámetro en las propiedades calculadas, es por eso que al llamar a cualquier propiedad de la computadora no se requiere paréntesis.

Métodos

Los métodos son iguales a la función y funcionan de la misma manera. Además, un método no hace nada a menos que lo llames. Además, como todas las funciones de JavaScript, acepta parámetros y se volverá a evaluar cada vez que se llame. Después de eso, no pueden almacenar en caché los valores

En el método que llama el paréntesis está ahí y puede enviar uno o más parámetros en eso.

Rajat
fuente
0

Tropecé con la misma pregunta. Para mí es más claro así:

  1. Cuando Vue.js ve v-on directiveseguido por un método, sabe exactamente a qué método llamar y cuándo llamarlo.
<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. Cuando se llama a un método sin elv-on directive , se llamará cada vez que se active un evento en la página que actualiza el DOM (o simplemente necesita volver a representar una parte de la página). Incluso cuando ese método no tiene nada que ver con el evento que se desencadena.
<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 propiedad calculada solo se llama cuando se cambia un valor de propiedad al que la thispalabra hace referencia en su definición de función.
<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.  */

La conclusión aquí es que es una buena práctica usar las computedpropiedades en caso de que no se llame a un método con v-on directive.

DarkLite1
fuente