web-dev-qa-db-fra.com

mapState avec setter

Je voudrais attribuer des méthodes de définition via mapState. J'utilise actuellement une solution de contournement dans laquelle je nomme la variable qui m'intéresse (todo) en tant que nom temporaire (storetodo), puis je m'y réfère dans une autre variable calculée todo .

methods: {
    ...mapMutations([
        'clearTodo',
        'updateTodo'
    ])
},
computed: {
    ...mapState({
        storetodo: state => state.todos.todo
    }),
    todo: {
        get () { return this.storetodo},
        set (value) { this.updateTodo(value) }
    }
}

Je voudrais sauter l'étape supplémentaire et définir le getter, setter directement dans mapState.

Pourquoi voudrais-je faire ça?

L'approche normale serait d'utiliser mapMutations/mapActions & mapState/mapGetters sans la combinaison get/set calculée que j'ai illustrée ci-dessus et pour référencer la mutation directement dans le HTML:

<input v-model='todo' v-on:keyup.stop='updateTodo($event.target.value)' />

La version getter/setter me permet d'écrire simplement:

<input v-model='todo' />
15
Chris

Vous ne pouvez pas utiliser un format getter/setter dans le mapState

ce que vous pouvez essayer, c'est retourner directement l'état dans votre get() et supprimer mapState de la propriété calculée

computed: {
    todo: {
        get () { return this.$store.state.todos.todo},
        set (value) { this.updateTodo(value) }
    }
} 

Voici une relation apparentée mais pas la même exemple JsFiddle

14
Vamsi Krishna

Ceci est ma solution de contournement actuelle. Copié de mon projet de travail personnel

// 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;
 }, {})
);

Dans votre fichier component.vue

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

vous pouvez maintenant utiliser les liaisons v-model. l

1
Kharel

Une autre façon d'approcher qui utilise store mutations comme ci-dessous:

//in your component js file:
this.$store.commit('setStoretodo', storetodo)

En supposant que vous définissez setStoretodo dans les mutations de votre instance de magasin vuex (ce qui est recommandé de toute façon):

//in your vuex store js file:
state:{...},
actions: {...}
...
mutations: {
    setStoretodo(state, val){
        state.storetodo = val
    },
    ...
}
...

Cela maintient la propriété réactive car mapState récupérera la valeur mise à jour et elle sera rendue automatiquement.

Ce n'est sûrement pas aussi cool que d'écrire this.storetodo = newValue, mais peut-être que quelqu'un trouvera cela utile aussi.

0
vir us