322 votes

Puis-je passer des paramètres dans les propriétés calculées dans Vue.Js ?

Est-il possible de passer des paramètres dans des propriétés calculées dans Vue.Js ? Je peux voir que lorsque l'on a des getters/setter utilisant le computed, ils peuvent prendre un paramètre et l'assigner à une variable. comme ici de documentation :

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

Est-ce également possible ?

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

Où la propriété calculée prend un argument et renvoie le résultat souhaité. Cependant, lorsque j'essaie de le faire, j'obtiens cette erreur :

vue.common.js:2250 Uncaught TypeError : fullName is not a function( )

Devrais-je utiliser des méthodes pour de tels cas ?

10 votes

Non, vous ne pouvez pas passer de paramètres aux propriétés calculées. Oui, l'utilisation de méthodes est le moyen le plus simple de le faire.

433voto

damienix Points 2399

Vous voulez probablement utiliser une méthode

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

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

Explication plus longue

Techniquement, vous pouvez utiliser une propriété calculée avec un paramètre comme ceci :

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

(Merci Unirgy pour le code de base de ceci).

La différence entre une propriété calculée et une méthode est que les propriétés calculées sont mises en cache et ne changent que lorsque leurs dépendances changent. A sera évaluée à chaque fois qu'elle sera appelée .

Si vous avez besoin de paramètres, il n'y a généralement aucun avantage à utiliser une fonction de propriété calculée plutôt qu'une méthode dans un tel cas. Bien que cela vous permette d'avoir une fonction getter paramétrée liée à l'instance Vue, vous perdez la mise en cache, donc pas vraiment de gain, en fait, vous pouvez casser la réactivité (AFAIU). Vous pouvez en savoir plus à ce sujet dans la documentation de Vue https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods

La seule situation utile est lorsque vous doivent utiliser un getter et avoir besoin de le paramétrer. Par exemple, cette situation se produit dans Vuex . Dans Vuex, c'est le seul moyen d'obtenir de manière synchrone un résultat paramétré à partir du magasin (les actions sont asynchrones). Ainsi cette approche est listée par la documentation officielle de Vuex pour ses getters https://vuex.vuejs.org/guide/getters.html#method-style-access

0 votes

Très complet, merci !

0 votes

Mais comment utiliser la fonction calculée ? Je veux dire où passer le paramètre. Cela ne fonctionne pas pour moi.

0 votes

Vous devez passer le paramètre à l'endroit où vous appelez votre prop calculé, très probablement dans votre modèle : {{ fullName('Joe') }} .

46voto

Unirgy Points 326

Vous pouvez utiliser des méthodes, mais je préfère encore utiliser des propriétés calculées plutôt que des méthodes, si elles ne mutent pas les données ou n'ont pas d'effets externes.

Vous pouvez passer des arguments aux propriétés calculées de cette façon (non documenté, mais suggéré par les mainteneurs, je ne me souviens plus où) :

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

EDIT : Veuillez ne pas utiliser cette solution, elle ne fait que compliquer le code sans aucun avantage.

0 votes

Il serait vraiment utile que vous puissiez fournir une référence. Cela devrait fonctionner.

0 votes

@saurabh désolé c'était une solution pour un problème pas vraiment descriptif dans github, et je ne peux pas le trouver maintenant....

0 votes

Cela fonctionne pour moi, mais la seule chose dont je ne suis pas fan est le fait qu'il renvoie une fonction plutôt que la propriété réelle, de sorte que le devtools VueJS ne montre pas les résultats nulle part. Je ne sais pas si c'est typique des propriétés calculées, mais cela rend le dépannage un peu plus difficile.

12voto

Eh bien, techniquement parlant, nous pouvons passer un paramètre à une fonction calculée, de la même manière que nous pouvons passer un paramètre à une fonction getter dans Vuex. Une telle fonction est une fonction qui renvoie une fonction.

Par exemple, dans les getters d'un magasin :

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

Ce getter peut être mis en correspondance avec les fonctions calculées d'un composant :

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

Et nous pouvons utiliser cette fonction calculée dans notre modèle comme suit :

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

Nous pouvons appliquer la même approche pour créer une méthode calculée qui prend un paramètre.

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

Et l'utiliser dans notre modèle :

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

Cela dit, je ne dis pas ici que c'est la bonne façon de faire les choses avec Vue.

Cependant, j'ai pu observer que lorsque l'élément avec l'ID spécifié est modifié dans le magasin, la vue rafraîchit automatiquement son contenu avec les nouvelles propriétés de cet élément (la liaison semble fonctionner parfaitement).

0 votes

Je n'utilise pas Vuex. Je voudrais aussi savoir si c'est une façon légitime de faire des propriétés calculées.

5 votes

Bien que cette méthode fonctionne, elle traite la propriété calculée de la même manière qu'une méthode, c'est-à-dire qu'elle perd les avantages de la mise en cache d'une propriété calculée. Il n'y a donc pas de gain réel à utiliser cette méthode plutôt qu'une méthode. "Notez que les getters auxquels on accède via des méthodes s'exécutent chaque fois que vous les appelez, et le résultat n'est pas mis en cache." Voir vuex.vuejs.org/fr/getters.html

0 votes

@james.brndwgn mais je suis presque sûr que les méthodes ne seront pas réexécutées lorsque les données sous-jacentes seront modifiées. C'est tout ce que je recherche vraiment.

5voto

roli roli Points 2157

Vous pouvez passer des paramètres, mais soit ce n'est pas une méthode vue.js, soit la méthode que vous utilisez est mauvaise.

Cependant, il y a des cas où vous devez le faire. Je vais vous montrer un exemple simple de passage de valeur à une propriété calculée en utilisant un getter et un setter.

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

Et le script

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

Lorsque nous cliquons sur le bouton, nous transmettons à la propriété calculée le nom 'Roland' et en set() nous changeons le nom de "John Doe" en "Roland".

Ci-dessous, il y a un cas d'utilisation commun où computed est utilisé avec getter et setter. Disons que vous avez le magasin Vuex suivant :

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

Et dans votre composant, vous voulez ajouter v-model à une entrée mais en utilisant le magasin 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>

0voto

Isometriq Points 81

Oui, il existe des méthodes pour utiliser les paramètres. Comme les réponses ci-dessus, dans votre exemple, il est préférable d'utiliser des méthodes puisque l'exécution est très légère.

À titre de référence uniquement, dans une situation où la méthode est complexe et le coût élevé, vous pouvez mettre les résultats en cache comme suit :

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

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

note : Lorsque vous utilisez cette méthode, faites attention à la mémoire si vous traitez avec des milliers de personnes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X