Search code examples
javascriptvue.jsvuexmutation

Watch and mutation in vuejs/vuex


So I managed to get to watch an element from state but I want also to update an element from state.

This is what I tried but it doesn't seam to work:

<template>
  <input :style="styleForX" ... />
</template>


// script in template file :: isXActive returns focus input = true/false
 watch: {
  isXActive: (isXActive) => {
    console.log(123);
    this.$store.commit("SET_STYLE_FOR_X", isXActive);
  },
},
computed: {
  ...mapGetters([
    "styleForX",
]);


// state.js
export default state = {styleForX: ""}

// getters.js
styleForX: (state) => {
  return state.styleForX;
},

// action.js
SET_STYLE_FOR_X({commit}, isXActive) {
  const style = isXActive? {backgroundColor: "white", zIndex: "51"} : "";
  commit("SET_STYLE_FOR_X", style);
},


// mutation.js
SET_STYLE_FOR_X(state, styleForX) {
  state.styleForX= styleForX;
}

Every js file has the export default statement. Any idea how should I make it work?

  1. Update:

Changed code to:

 watch: {
  isXActive: () => {
    this.$store.commit("SET_STYLE_FOR_X", {backgroundColor: "white", zIndex: "51"});
  },

but still doesn't work. I get this as undefined, so I get this error:

Error in callback for watcher "isXActive": "TypeError: Cannot read property '$store' of undefined" found in ...
  1. Update - I changed it to this and this works. But still if anyone knows how to make the first version work please drop a comment. Thank you!
created() {
  this.$store.watch(
    () => this.$store.state.isXActive,
    () => {
      this.$store.commit("SET_STYLE_FOR_X", {backgroundColor: "white", zIndex: "51"});
    }
  );
}
  1. Update - because the style was not remove on focus out I changed it again to:
created() {
  this.$store.watch(
    () => this.$store.state.isXActive,
    () => {
      this.$store.dispatch("SET_STYLE_FOR_X", isXActive);
    }
  );
}

// action.js
SET_STYLE_FOR_X({commit}, isXActive) {
  const style = isXActive? {backgroundColor: "white", zIndex: "51"} : "";
  commit("SET_STYLE_FOR_X", style);
},

  1. Update - end result
 watch: {
  isXActive() {
    this.$store.commit("SET_STYLE_FOR_X", this.$store.state.isXActive);
  },

Thank you eli chen !!


Solution

  • In your watch handler, you are calling this.$store.commit when it appears you intend to call this.$store.dispatch(). commit runs a mutation. dispatch runs an action. Your code for calculating the style from the boolean value is in the action, therefore you should use dispatch.

    That said, there is no reason to use an action here since you don't have any asynchronous code. Simply put the logic for the style string inside the mutation instead of in the action.