精通Vue.js系列 │ Vuex中的异步操作

简介: Vuex中异步操作

640.jpg


在仓库的actions选项的动作函数中,可以包含异步操作,例如以下actionA()动作函数会异步提交someMutation()更新函数。


actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

以下代码在一个组件的方法忠派发actionA()动作函数。


this.$store.dispatch('actionA').then(() => {
  // 当actionA()动作函数中的异步操作执行完毕后,再执行then()函数指定的操作
  …
})

在仓库的一个动作函数中还可以派发另一个动作函数:

actions: {
  //…
  actionB ({ dispatch, commit }) {  //actionB()函数派发actionA()函数
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}

此外,还可以通过async/await执行异步操作,例如:


//假定getData()和getOtherData()返回Promise对象
actions: {
  async actionA ({ commit }) {  //async表明当前函数包含异步操作
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') //等待actionA()的异步操作执行完毕
    commit('gotOtherData', await getOtherData())
  }
}

1、异步动作范例

以下位于src/main.js中的代码创建了一个包含actions选项的仓库store,包括addQuantityAction()和calculateAction()动作函数。

const store = createStore({
  state () {
    return {
      item: {
        name: '苹果',
        price: 3.8,
        quantity: 1,
        total :  3.8
      }
    }
  },

  mutations: {
    addQuantity(state){  //增加购买数量
      state.item.quantity++
    },
    calculate(state){  //计算总价格
     state.item.total=state.item.price * state.item.quantity
    }
  },

  actions: {
    addQuantityAction({commit}){
      return new Promise((resolve)=>{
        setTimeout(          //模拟异步操作
          ()=>{
             commit('addQuantity')
             resolve() 
          },2000)
      })
    },

    calculateAction({commit,dispatch}){
      //等购买数量增加后,再计算总价格 
      dispatch('addQuantityAction').then( ()=>{
        commit('calculate')
      })
    }
  }
})

以上代码中的动作函数的作用如下。

(1)addQuantityAction()动作函数:包含异步操作,过2秒后提交addQuantity()更新函数。

(2)calculateAction()动作函数:会派发addQuantityAction()动作函数,等到addQuantityAction()动作函数的异步操作执行完毕以后,再执行then()函数,从而提交calculate()更新函数。

例程1的AsyncJudge.vue定义了AsyncJudge组件,它的calculate()方法会向仓库派发calculateAction()动作函数。

■ 例程1 AsyncJudge.vue


<template>
  <div>
    <p>商品名字: {{item.name}}  </p>
    <p>单价: {{item.price}}  </p>
    <p>数量: {{item.quantity}}  
    <button @click="calculate">增加</button>  </p>
    <p>总价:{{item.total}}</p> 
  </div>
</template>
  
<script>
  import { mapState,mapActions } from 'vuex'

  export default {
    computed: mapState(['item']),
  
    methods: {
      ...mapActions({calculate: 'calculateAction'})  
    }
  }
</script>

在src/router/index.js中,为AsyncJudge组件设置的路由的路径为judge。通过浏览器访问http://localhost:8080/#/judge,会出现如图1所示的网页。在网页上单击“增加”按钮,就会看到在延迟2秒后,{{item.quantity}}及{{item.total}}的取值会发生相应的更新。

640.png


■ 图1 AsyncJudge组件的页面

2、使用async/await的范例

以下位于src/main.js中的代码创建了一个包含actions选项的仓库store,包括一个loadCustomerAction()动作函数,该动作函数用async标识,表明是包含异步操作的函数。


const store = createStore({
  state () {
    return {
      customer: '', 
      msg: ''
    }
  },

  mutations: {
    clearCustomer(state){
      state.msg='正在查询...'
      state.customer=''
    },
    loadCustomer(state,response){
      if(response.data !== null){
        state.customer=response.data
        state.msg=''
      }else
        state.msg='未找到匹配的数据!'    
    }
  },

  actions: {
    async loadCustomerAction({commit},id){
      commit('clearCustomer')  
      const response=await axios({
         baseURL: 'http://www.javathinker.net',
         url: '/customer',
         method: 'get',
         params: {id: id}
      })
      commit('loadCustomer',response) 
    }
  }
})

loadCustomerAction()动作函数会通过Axios请求访问服务器,查询与id匹配的customer对象。在异步调用axios()函数之前,会提交clearCustomer()更新函数,等到Axios的异步请求执行完毕,再提交loadCustomer()更新函数。

例程2的AsyncCustomer.vue定义了AsyncCustomer组件。它的getCustomer()方法会向仓库派发loadCustomerAction()动作函数。

■ 例程2 AsyncCustomer.vue


<template>
  <div>
    <p>输入id: <input v-model="id" />  
           <button @click="getCustomer">查询</button>  {{msg}} 
    </p>  
    <p>{{customer}}</p>
  </div>
</template>
  
<script>
  import {mapState} from 'vuex'
  export default {
    data(){ return {id: '' }},
    computed: mapState(['customer','msg']),
    methods: {
      getCustomer(){
        this.$store.dispatch('loadCustomerAction',this.id).then(
          ()=>{console.log(this.customer)}
        )
      }
    }
  }
</script>

在src/router/index.js中,为AsyncCustomer组件设置的路由的路径为cust。通过浏览器访问http://localhost:8080/#/cust,会出现如图2所示的网页。在网页上的id输入框输入1,再单击“查询”按钮,会看到网页先显示“正在查询...”,延迟一段时间后,再显示id为1的customer对象的信息。

640.png

■ 图2 AsyncCustomer组件的页面

目录
相关文章
|
1月前
|
存储 JavaScript 前端开发
前端技术分享:使用Vue.js与Vuex管理状态
【10月更文挑战第1天】前端技术分享:使用Vue.js与Vuex管理状态
46 6
|
2月前
|
JavaScript
Vue3基础(24)___vue3中使用vuex
本文介绍了在Vue 3中如何使用Vuex进行状态管理,包括安装Vuex、创建store、定义state、mutations、actions、getters,以及在组件中使用这些选项。同时,还介绍了如何通过`$store`在组件内部访问和修改状态,以及如何使用命名空间对模块进行隔离。
93 3
|
10天前
|
JSON 前端开发 JavaScript
在 JavaScript 中,如何使用 Promise 处理异步操作?
通过以上方式,可以使用Promise来有效地处理各种异步操作,使异步代码更加清晰、易读和易于维护,避免了回调地狱的问题,提高了代码的质量和可维护性。
|
2月前
|
JavaScript
在 Vue 3 组件通信方式中,Provide / Inject 与 Vuex 的区别是什么?
在 Vue 3 组件通信方式中,Provide / Inject 与 Vuex 的区别是什么?
136 65
|
14天前
|
存储 JavaScript
Vue 状态管理工具vuex
Vue 状态管理工具vuex
|
22天前
|
监控 JavaScript 前端开发
Vue 异步渲染
【10月更文挑战第23天】Vue 异步渲染是提高应用性能和用户体验的重要手段。通过理解异步渲染的原理和优化策略,我们可以更好地利用 Vue 的优势,开发出高效、流畅的前端应用。同时,在实际开发中,要注意数据一致性、性能监控和调试等问题,确保应用的稳定性和可靠性。
|
1月前
|
JavaScript
《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
《进阶篇第9章》学习vuex知识点后练习:求和案例_纯vue版代码
13 1
|
1月前
|
存储 JavaScript 前端开发
深入理解 Vuex:Vue.js 状态管理的利器
【10月更文挑战第11天】 深入理解 Vuex:Vue.js 状态管理的利器
34 2
|
1月前
|
前端开发 JavaScript 开发者
JS 异步解决方案的发展历程以及优缺点
本文介绍了JS异步解决方案的发展历程,从回调函数到Promise,再到Async/Await,每种方案的优缺点及应用场景,帮助开发者更好地理解和选择合适的异步处理方式。
|
2月前
|
存储 JavaScript API
Vue3基础(25)___初尝pinia,相比于vuex轻量、好用
本文介绍了Pinia在Vue 3中的使用,相比于Vuex,Pinia更轻量且易于使用。文章详细解释了Pinia的基本概念、优势,并提供了安装和使用Pinia的步骤,包括定义状态、getters、actions和如何在组件中使用Pinia进行状态管理。
54 3
Vue3基础(25)___初尝pinia,相比于vuex轻量、好用