¿Puedo pasar parámetros en propiedades calculadas en Vue.Js?
¿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?
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 Unirgy
por 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
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.
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).