How to fire an event on Vue switch change

2019-06-14 01:26发布

I have a Vue component that has a vue-switch element. When the component is loaded, the switch has to be set to ON or OFF depending on the data. This is currently happening within the 'mounted()' method. Then, when the switch is toggled, it needs to make an API call that will tell the database the new state. This is currently happening in the 'watch' method.

The problem is that because I am 'watching' the switch, the API call runs when the data gets set on mount. So if it's set to ON and you navigate to the component, the mounted() method sets the switch to ON but it ALSO calls the toggle API method which turns it off. Therefore the view says it's on but the data says it's off.

I have tried to change the API event so that it happens on a click method, but this doesn't work as it doesn't recognize a click and the function never runs.

How do I make it so that the API call is only made when the switch is clicked?

HTML

<switcher size="lg" color="green" open-name="ON" close-name="OFF" v-model="toggle"></switcher>  

VUE

data: function() {
    return {
        toggle: false,
        noAvailalableMonitoring: false
    }
},
computed: {
    report() { return this.$store.getters.currentReport },
    isBeingMonitored() { return this.$store.getters.isBeingMonitored },
    availableMonitoring() { return this.$store.getters.checkAvailableMonitoring }
},
mounted() {
    this.toggle = this.isBeingMonitored;
},
watch: {
    toggle: function() {
      if(this.availableMonitoring) {
          let dto = {
            reportToken: this.report.reportToken,
            version: this.report.version
          }
          this.$store.dispatch('TOGGLE_MONITORING', dto).then(response => {
          }, error => {
          console.log("Failed.")
      }) 
    } else {
        this.toggle = false;
        this.noAvailalableMonitoring = true;
    }
  }
}

2条回答
一纸荒年 Trace。
2楼-- · 2019-06-14 01:47

I would recommend using a 2-way computed property for your model (Vue 2). Attempted to update code here, but obvs not tested without your Vuex setup. For reference, please see Two-Way Computed Property

data: function(){
  return {
    noAvailableMonitoring: false
  }
},
computed: {
  report() { return this.$store.getters.currentReport },
  isBeingMonitored() { return this.$store.getters.isBeingMonitored },
  availableMonitoring() { return this.$store.getters.checkAvailableMonitoring },
  toggle: {
    get() {
      return this.$store.getters.getToggle;
    },
    set() {
      if(this.availableMonitoring) {
        let dto = {
          reportToken: this.report.reportToken,
          version: this.report.version
        }
        this.$store.dispatch('TOGGLE_MONITORING', dto).then(response => {
        }, error => {
          console.log("Failed.")
        });
      } else {
        this.$store.commit('setToggle', false);
        this.noAvailableMonitoring = true;
      }
    }
  }
}
查看更多
Anthone
3楼-- · 2019-06-14 01:51

Instead of having a watch, create a new computed named clickToggle. Its get function returns toggle, its set function does what you're doing in your watch (as well as, ultimately, setting toggle). Your mounted can adjust toggle with impunity. Only changes to clickToggle will do the other stuff.

查看更多
登录 后发表回答