MapState with setter

I would like to assign setter methods with mapState

. I am currently using a workaround where I call the variable of interest ( todo

) as a temporary name ( storetodo

) and then reference it in another computed variable todo

.

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

      

I would like to skip an extra step and define a getter, setter directly in mapState

.

Why would I do this?

The usual approach would be to use mapMutations

/ mapActions

and mapState

/ mapGetters

without the computed get / set combination I illustrated above, and referencing the mutation directly in HTML:

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

      

The getter / setter version allows me to simply write:

<input v-model='todo' />

      

+3


source to share


2 answers


You cannot use getter / setter format in mapState

what you can try is directly returns the state in get()

and removes mapState

from the computed property



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

      

Here is a related but wrong JsFiddle example

+3


source


This is my current solution. Copied from my personal working project

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

      

In the component.vue file



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

      

you can now use v-model bindings. l

0


source







All Articles