|  | 本文参考孙卫琴,杜聚宾所创作的 <<精通Vue.js: Web前端开发技术详解>>一书 
 在仓库的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}}的取值会发生相应的更新。
 
   图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对象的信息。
 
   图2  AsyncCustomer组件的页面
 
 
 
 
 程序猿的技术大观园:www.javathinker.net
 |  |