¿Puedo pasar parámetros en propiedades calculadas en Vue.Js?

Resuelto Saurabh asked hace 8 años • 13 respuestas

¿Es posible pasar parámetros en propiedades calculadas en Vue.Js? Puedo ver que cuando se calculan los captadores/definidores, pueden tomar un parámetro y asignarlo a una variable. como aquí de la documentación :

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
  
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

¿Es esto también posible?

computed: {
  fullName: function (salut) {
    return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}

Donde la propiedad calculada toma un argumento y devuelve el resultado deseado. Sin embargo, cuando intento esto, aparece este error:

vue.common.js: 2250 Error de tipo no detectado: el nombre completo no es una función (…)

¿Debería utilizar métodos para tales casos?

Saurabh avatar Nov 10 '16 15:11 Saurabh
Aceptado

Lo más probable es que quieras utilizar un método

<span>{{ fullName('Hi') }}</span>

methods: {
  fullName(salut) {
      return `${salut} ${this.firstName} ${this.lastName}`
  }
}

Explicación más larga

Técnicamente puedes usar una propiedad calculada con un parámetro como este:

computed: {
   fullName() {
      return salut => `${salut} ${this.firstName} ${this.lastName}`
   }
}

(Gracias Unirgypor el código base para esto).

La diferencia entre una propiedad calculada y un método es que las propiedades calculadas se almacenan en caché y cambian sólo cuando cambian sus dependencias. Un método se evaluará cada vez que se llame .

Si necesita parámetros, normalmente no hay beneficios al utilizar una función de propiedad calculada en lugar de un método en tal caso. Aunque le permite tener una función getter parametrizada vinculada a la instancia de Vue, pierde el almacenamiento en caché, por lo que realmente no hay ninguna ganancia allí; de hecho, puede interrumpir la reactividad (AFAIU). Puede leer más sobre esto en la documentación de Vue https://v2.vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods

La única situación útil es cuando tienes que usar un captador y necesitas parametrizarlo. Por ejemplo, esta situación ocurre en Vuex . En Vuex, es la única forma de obtener resultados parametrizados de la tienda de forma sincrónica (las acciones son asíncronas). Por lo tanto, este enfoque figura en la documentación oficial de Vuex para sus captadores https://vuex.vuejs.org/guide/getters.html#method-style-access

damienix avatar Nov 11 '2016 00:11 damienix

Puede usar métodos, pero prefiero usar propiedades calculadas en lugar de métodos, si no están mutando datos o no tienen efectos externos.

Puede pasar argumentos a las propiedades calculadas de esta manera (no documentado, pero sugerido por los mantenedores, no recuerdo dónde):

computed: {
   fullName: function () {
      var vm = this;
      return function (salut) {
          return salut + ' ' + vm.firstName + ' ' + vm.lastName;  
      };
   }
}

No utilice esta solución, solo complica el código sin ningún beneficio.

Unirgy avatar Jan 05 '2017 00:01 Unirgy

Bueno, técnicamente hablando podemos pasar un parámetro a una función calculada, de la misma manera que podemos pasar un parámetro a una función getter en vuex. Tal función es una función que devuelve una función.

Por ejemplo, en los captadores de una tienda:

{
  itemById: function(state) {
    return (id) => state.itemPool[id];
  }
}

Este captador se puede asignar a las funciones calculadas de un componente:

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ])
}

Y podemos usar esta función calculada en nuestra plantilla de la siguiente manera:

<div v-for="id in ids" :key="id">{{itemById(id).description}}</div>

Podemos aplicar el mismo enfoque para crear un método calculado que tome un parámetro.

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ]),
  descriptionById: function() {
    return (id) => this.itemById(id).description;
  }
}

Y úsalo en nuestra plantilla:

<div v-for="id in ids" :key="id">{{descriptionById(id)}}</div>

Dicho esto, no estoy diciendo aquí que sea la forma correcta de hacer las cosas con Vue.

Sin embargo, pude observar que cuando el elemento con el ID especificado muta en la tienda, la vista actualiza su contenido automáticamente con las nuevas propiedades de este elemento (el enlace parece estar funcionando bien).

Stéphane Appercel avatar Jan 26 '2018 14:01 Stéphane Appercel