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


Es esto posible pasar el parámetro en propiedades calculadas en Vue.Js. Puedo ver que al tener getters / setter usando computado, pueden tomar un parámetro y asignarlo a una variable. como aquí de 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 la salida deseada. Sin embargo, cuando intento esto, estoy recibiendo este error:

SDV.común.js: 2250 Uncaught TypeError: FullName no es un función(...)

¿Debo usar métodos para tales casos?

Author: Saurabh, 2016-11-10

6 answers

Lo más probable es que desee utilizar un método:

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

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

Explicación más larga

Técnicamente se puede 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 la propiedad calculada y el método es que las propiedades calculadas se almacenan en caché y cambian solo cuando cambian sus dependencias. Un método evaluará cada vez que se llame. No hay beneficios de utilizar este enfoque sobre una propiedad calculada tal caso. Puede leer más sobre esto en la documentación del SDV https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods

Esta situación es ligeramente diferente cuando se usa Vuex. AFAIK en Vuex es la única manera de obtener sincrónicamente el resultado parametrizado de la tienda (las acciones son asíncronas). Por lo tanto, este enfoque está listado por la documentación oficial de Vuex para sus captadores https://vuex.vuejs.org/guide/getters.html#method-style-access

 94
Author: damienix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-22 21:22:59

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

EDITAR: Por favor, no utilice esta solución, solo complica el código sin ningún beneficio.

 14
Author: Unirgy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-06 01:41:36

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. Esta función es una función que devuelve una función.

Por ejemplo, en los getters de una tienda:

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

Este getter 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 computado método que toma 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 es la manera correcta de hacer las cosas con Vue.

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

 4
Author: Stéphane Appercel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-26 14:02:22

Sí existen métodos para usar parámetros. Al igual que las respuestas mencionadas anteriormente, en su ejemplo es mejor usar métodos ya que la ejecución es muy ligera.

Solo como referencia, en una situación donde el método es complejo y el costo es alto, puede almacenar en caché los resultados de la siguiente manera:

data() {
    return {
        fullNameCache:{}
    };
}

methods: {
    fullName(salut) {
        if (!this.fullNameCache[salut]) {
            this.fullNameCache[salut] = salut + ' ' + this.firstName + ' ' + this.lastName;
        }
        return this.fullNameCache[salut];
    }
}

Nota: Al usar esto, vigile la memoria si se trata de miles

 0
Author: Isometriq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-16 04:53:35

Puede pasar parámetros, pero o bien no es un vue.js manera o la forma en que lo estás haciendo está mal.

Sin embargo, hay casos en los que es necesario hacerlo.Voy a mostrarles un ejemplo simple pasando el valor a la propiedad calculada usando getter y setter.

<template>
    <div>
        Your name is {{get_name}} <!-- John Doe at the beginning -->
        <button @click="name = 'Roland'">Change it</button>
    </div>
</template>

Y el script

export default {
    data: () => ({
        name: 'John Doe'
    }),
    computed:{
        get_name: {
            get () {
                return this.name
            },
            set (new_name) {
                this.name = new_name
            }
        },
    }    
}

Cuando el botón hace clic estamos pasando a la propiedad computada el nombre 'Roland' y en set() estamos cambiando el nombre de 'John Doe' a 'Roland'.

Debajo hay un el caso de uso común cuando se computa se usa con getter y setter. Digamos que tienes la siguiente tienda vuex:

export default new Vuex.Store({
  state: {
    name: 'John Doe'
  },
  getters: {
    get_name: state => state.name
  },
  mutations: {
    set_name: (state, payload) => state.name = payload
  },
})

Y en su componente desea agregar v-model a una entrada pero utilizando la tienda vuex.

<template>
    <div>
        <input type="text" v-model="get_name">
        {{get_name}}
    </div>
</template>
<script>
export default {
    computed:{
        get_name: {
            get () {
                return this.$store.getters.get_name
            },
            set (new_name) {
                this.$store.commit('set_name', new_name)
            }
        },
    }    
}
</script>
 0
Author: roli roli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-24 06:09:52

No estoy completamente seguro de lo que está tratando de lograr, pero parece que estará perfectamente bien utilizando el método en lugar de computado!

 -1
Author: M U,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-10 08:40:19