Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js disable component during ajax request

I'm looking for a simple solution for the following problem:

I have a Vue component button with which I can make an ajax request. I would like to disable this button while the request is pending (to prevent multiple requests).

like image 782
pharkasbence Avatar asked Aug 22 '18 13:08

pharkasbence


People also ask

How do I deactivate a component Vue?

Vue Button component can be enabled/disabled by giving disabled property. To disable Vue Button component, the disabled property can be set as true .

How do I conditionally disable a button in Vuejs?

To disable a button in Vue. js, we set the disabled prop of the button. to set the disabled prop to the isDisabled reactive property. Therefore, the disabled attribute will be added to the button only if isDisabled is true .

How do I switch between VUE components?

You need to bind the value into the component and then emit a new value to the parent when you click a link. If you emit the event input and bind the value value , then you can use v-model .

Does Vue reuse components?

Since components are reusable Vue instances, they accept the same options as new Vue , such as data , computed , watch , methods , and lifecycle hooks. The only exceptions are a few root-specific options like el .


1 Answers

Sounds like you want your action to set (commit) a flag when it starts and then clear it when it ends.

Try something like this in Vuex...

state: {
  loading: false
},
mutations: {
  isLoading (state) {
    state.loading = true
  },
  doneLoading (state) {
    state.loading = false
  }
},
actions: {
  doAjaxRequest ({ commit }) {
    commit('isLoading')
    return doSomeAjaxRequest().then(res => {
      // success
    }).catch(err => {
      // oh noes
    }).finally(() => {
      commit('doneLoading')
    })
  }
}

Now in your component, you can map the loading state and use it to disable your button, eg

<template>
  <button :disabled="loading" @click="doAjaxRequest">Do AJAX!</button>
</template>
<script>
  import { mapState, mapActions } from 'vuex'
  export default {
    computed: mapState(['loading']),
    methods: mapActions(['doAjaxRequest'])
  }
</script>

Alternatively, you can maintain the progress of the request within your component if your action returns a promise (as above). For example, say your button has

<button :disabled="loading" @click="doTheThing">Do the thing!</button>

and

data () {
  return { loading: false }
},
methods: {
  doTheThing() {
    this.loading = true
    this.$store.dispatch('someAjaxActionThatReturnsAPromise').finally(() => {
      this.loading = false
    })
  }
}
like image 115
Phil Avatar answered Oct 08 '22 14:10

Phil