web-dev-qa-db-fra.com

passer le paramètre aux getters dans Vuex

J'ai un composant Vue comme ceci:

<script>
import { mapActions, mapGetters } from 'vuex'

export default {
  props: ['index'],
  computed: {
    ...mapGetters([
      'type',
      'width',
      'height',
      'description',
      'smtTagMeasureUnits',
      'tagValue'
    ])
  }
</script>

<template>
  <div :class='["block","module-"+type(index), "width"+width(index), "height"+height(index)]'>
    <h3>{{ description(index) }}</h3>
    <div class="data">
      <h1>{{ tagValue(index) }}</h1>
      <h2 class="measure">{{ smtTagMeasureUnits(index) }}</h2>
    </div>
  </div>
</template>

<style>
  ...
</style>

Paramètre index, qui entre en composant en tant que accessoire , a été transmis avec succès aux getters:

getters: {
  ...
  type: (state, getters) => (par) => {
    return getters.widgetsConfig[par].type
  },
  width: (state, getters) => (par) => {
    if (getters.widgetsConfig[par].width) {
      return getters.widgetsConfig[par].width
    } return 2
  },
  height: (state, getters) => (par) => {
    if (getters.widgetsConfig[par].height) {
      return getters.widgetsConfig[par].height
    } return 1
  },
  ...
}

Fonctionne bien, mais je ne suis pas satisfait de ce codestyle, car getterName(index) se répète constamment dans la partie modèle. Tous mes getters devraient porter l'index comme accessoire, donc je voudrais avoir juste getterName dans le modèle et quelque chose comme ça dans la partie script:

...mapGetters([
'type',
'width',
'height',
'description',
'smtTagMeasureUnits',
'tagValue'
], index)

Est-il possible de réaliser des améliorations de codestyle ici?

7
KrasnokutskiyEA

Si vous voulez garder les choses SÈCHES, il serait judicieux de tirer parti de la logique d'obtention des informations d'élément (entité à laquelle index correspond) dans le magasin, de sorte que le composant ne reçoit que des données complètes prêtes à être rendues.

La solution suggérée consiste à créer un getter unique, qui accepte index comme argument et renvoie la liste complète des options de getters.widgetsConfig.

Notez que si nécessaire, d'autres getters peuvent être réutilisés afin de collecter les informations nécessaires dans un seul objet.

Mise en œuvre possible:

getters: {
  ...
  getItemByIndex: (state, getters) => (index) => {
    const { type, height, width } = getters.widgetsConfig[index]
    return {
      type,
      height,
      width
    }
  },
}

Et mettez à jour le composant pour mapper un seul getter et l'utiliser dans la propriété calculée:

computed: {
  ...mapGetters([
    'getItemByIndex'
  ]),
  item () {
    return this.getItemByIndex(index)
  }
}

Et toutes les propriétés seront accessibles à l'intérieur d'un modèle via item.type, item.height, item.width, etc..

4
aBiscuit

Vous pouvez toujours créer des propriétés calculées qui renvoient le résultat des getters. Quelque chose comme:

export default {
  props: ['index'],
  computed: {
    ...mapGetters([
      'getTypeFromIndex',
      'getWidthFromIndex',
      'getHeightFromIndex'
    ]),
    height(): { return this.getHeightFromIndex(index) },
    width(): { return this.getWidthFromIndex(index) },
    type(): { return this.getTypeFromIndex(index) },

    //going a step further to clean up your templates...
    classList: [
        "block", 
        "height"+this.height,
        "width"+this.width,
    ]
  }

De cette façon, vous avez juste besoin de height dans vos modèles au lieu de height(index), ou même simplement classList si vous allez aussi loin

Ceci est également référencé ici: https://github.com/vuejs/vuex/issues/688 et je ne le trouve pas mais je sais que j'ai vu celui recommandé par Evan You dans un github problème aussi.

3
Jeff