DEV Community

Jiří Procházka
Jiří Procházka

Posted on

Vue/Vuex ...mapComputed

When you are binding directly a Vuex state property to the form via v-model you need to create Two-way Computed Property like this:

// MyComponent.vue
<input v-model="email">
Enter fullscreen mode Exit fullscreen mode
// MyComponent.vue
...
computed: {
    email: {
      get() {
        return this.$store.state.email;
      },
      set(value) {
        this.$store.commit('setEmail', value)
      }
    }
}
...
Enter fullscreen mode Exit fullscreen mode

Doing this for each property is annoying and verbose. Fortunately we can inspire in Vuex mapGetters, mapMutations and mapActions methods and create our own mapComputed method:

// mapComputed.js
export const mapComputed = (module, fields) => {
  const obj = {};
  fields.forEach(field => {
    obj[field.name] = {
      get() {
        return this.$store.getters[`${module}/${field.getter}`];
      },
      set(value) {
        this.$store.commit(`${module}/${field.setter}`, value, { root: true });
      }
    };
  });
  return obj;
};
Enter fullscreen mode Exit fullscreen mode

The usage is simple then:

// MyComponent.vue
...
computed: {
    ...mapComputed("user", [
      { name: "email", getter: "getEmail", setter: "setEmail" }
    ]),
...
Enter fullscreen mode Exit fullscreen mode

Where name is the name of the computed property used in v-model, getter is the name of getter and setter is the name of used setter.

This is only the simple version considering using modules only.

Top comments (0)