3
votes

Comment utiliser élégamment v-model et Vuex store?

Je recherche une manière propre d'utiliser v-model et vuex store.

Vuex fournit plusieurs méthodes helpers qui sont assez utiles mais un peu ennuyeuses lors de l'utilisation avec v-model.

La manière Je fais aujourd'hui pour utiliser v-model et mon magasin modulaire est comme

computed: {
  ...mapState(['type']) // No need here to specify module name :)
}

Cela fonctionne MAIS j'ai trouvé préférable de profiter des helpers vuex pour éviter le code standard (ceci. $ Store , nom du module, ...)

Ok, donc je veux d'abord me débarrasser du nom du module. Vuex fournit un excellent createNamespacedHelpers qui renvoie des helpers modulaires.

Utilisons-le:

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')

Alors, ok, nous avons maintenant des fonctions propres mapState et mapActions qui sont dédiées au module.

computed: {
  type: {
    get() {
      return this.$store.state.mymodule.type;
    },
    set(newValue) {
      this.$store.dispatch('mymodule/setType', newValue)
    }
}

Assez cool mais comme mapState n'a que la fonction get, je ne peux pas définir une fonction de répartition pour mettre à jour les données ...

En cas d'utilisation de v-model, je trouve les helpers inutilisables. Je ne peux pas utiliser mapState, donc je ne peux pas utiliser createNamespacedHelpers.

Alors: Comment puis-je utiliser les avantages des fonctions d'aide de Vuex et du v-model pour travailler ensemble?


2 commentaires

pourquoi vous n'avez pas fait : value = "computedValue" & @ input = "setterFunction" dans votre composant?


On dirait que vous pourriez créer une fonction d'assistance qui produirait des calculs réglables et l'utiliser comme si vous utilisiez ... mapState .


3 Réponses :


2
votes

Vous ne pouvez pas. Il n'y a pas de moyen élégant de combiner les aides avec le modèle en V. Mais le v-model n'est qu'un sucre syntaxique, donc peut-être que le moyen le plus lisible est d'utiliser les helpers

<input :value="type" @input="setType">

sans le v-model

computed: {
  ...mapGetters('path/to/module', ['type'])
},
methods: {
  ...mapActions('path/to/module', ['setType'])
}


0 commentaires

1
votes

La façon dont j'ai finalement trouvé le plus lisible est la suivante:

<input :value="type" @input="setType($event.target.value)">

Utilisé comme ceci:

computed: {
  ...mapGetters(['type'])
},
methods: {
  ...mapActions(['setType'])
}

Et sans le v- modèle

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')


0 commentaires

0
votes

Essayez ceci.

  import { mapSetter  } from 'path/to/utils/vuex.js';
  ...

  export default {
    name: 'ComponentName',
    computed: {
      ...mapSetter(
        mapState({
          result: ({ ITEMS }) => ITEMS.result,
          total: ({ ITEMS }) => ITEMS.total,
          current: ({ ITEMS }) => ITEMS.page,
          limit: ({ ITEMS }) => ITEMS.limit,
        }),
        {
          limit(payload) {
            this.$store.dispatch({ type: TYPES.SET_LIMIT, payload });
          },
        },
      )
    },
  }

Dans votre fichier component.vue

// in some utils/vuex.js file 
export const mapSetter = (state, setters = {}) => (
  Object.keys(state).reduce((acc, stateName) => {
    acc[stateName] = {
      get: state[stateName],
   };
   // check if setter exists
   if (setters[stateName]) {
      acc[stateName].set = setters[stateName];
   }

   return acc;
 }, {})
);

la liaison v-model devrait maintenant fonctionner.


0 commentaires