Vue.js disable component during ajax request

后端 未结 3 1410
执念已碎
执念已碎 2021-01-13 03:52

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 butto

相关标签:
3条回答
  • 2021-01-13 04:12

    State.js:

    state: {
      pendingRequest: false
    },
    actions: {
      fetchRequest: async function(context) {
        context.state.pendingRequest = true
        let req = await fetch(url)
        let data = await req.json()
        context.state.pendingRequest = false
      }
    }
    

    Component.vue:

    <button :disabled='$store.state.pendingRequest' @click="$store.dispatch('fetchRequest')">Button</button>
    
    0 讨论(0)
  • 2021-01-13 04:18

    I found another solution: It automatically generates a vuex module for the registered endpoints, watch those endpoints via axios interceptors and sets the proper 'pending' state values based on the status of the related requests.

    https://github.com/pharkasbence/pending-request-tracker

    0 讨论(0)
  • 2021-01-13 04:20

    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
        })
      }
    }
    
    0 讨论(0)
提交回复
热议问题