暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

454

Vuex中异步操作


在仓库的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组件的页面




                  3

                  参考书籍

                  点击上图看详细图书介绍

                  《精通Vue.js:Web前端开发技术详解(微课视频版)》

                  详细阐述用Vue框架的各种技术;深刻揭示前端开发的响应式编程核心思想;介绍与其他流行技术的整合;典型范例帮助读者迅速获得实战经验。

                  ISBN:9787302602903

                  作者:孙卫琴,杜聚宾

                  价格:119元

                  扫码优惠购书

                  实例讲解

                  精通Vue.js:

                  Web前端开发技术详解

                  精彩回顾

                  1. Vue组件的命名规则

                  2. 注册全局组件和局部组件

                  3. 路由导航中抓取数据

                  4. 路由管理器的基本用法

                  5. 命名路由

                  6. CSS中DOM元素的过渡模式

                  7. 插槽slot的基本用法

                  8. 组件的递归

                  9. 在Vue项目中使用Axios

                  10. 自定义指令v-drag范例




                  下期预告

                  12. 分割setup函数

                  13. Vue组件的单向数据流

                  14. Vue的数据监听




                  文章转载自清华计算机学堂,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论