美文网首页前端透视镜
vuex action回调函数

vuex action回调函数

作者: 我啊翔1314 | 来源:发表于2019-01-23 10:12 被阅读72次

    我们知道, Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
    这个状态自管理应用包含以下几个部分:

    • state,驱动应用的数据源;
    • view,以声明方式将 state 映射到视图;
    • actions,响应在 view 上的用户输入导致的状态变化。

    对于state数据源的处理,分为两种类型的操作:

    • mutations. mutations方法内可直接修改state数据源,相当于setter方法,但这些方法内不允许执行异步操作。
    • getters. 用于获取一些基于state数据源的计算值。getters方法只能读取state数据源的值,不能修改state数据源。

    vuex整体大致架构如下:

    vuex架构.png
    可以看出,整个流程是单向的、闭环的。这符合状态管理模式的特点。

    1.Action

    Action的作用与Mutations类似,但它与Mutations有如下区别:

    • Action修改数据源是通过commit Mutations的方式来实现
    • Action支持执行异步操作

    一个简单的action示例如下:

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('increment')
        }
      }
    })
    

    2.Action函数回调

    在某些情况下,我们可能需要在action执行完成后做一些操作,那么就要在action执行完成后,回调一个函数回来。那么,你可能会想着在payload里面添加一个回调函数的变量,如下:

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment ({commit}, payload) {
          context.commit('increment')
          if (payload.success) payload.success()
        }
      }
    })
    

    然后在页面中dispatch action:

    this.$store.dispatch("increment", {
        success() {
            alert("incremented!")
        }
    })
    

    通过这种方式回调函数虽然会执行,但是会存在如下问题:

    • 如果commit mutation中包含payload变量的属性,且该属性是一个对象列表,那么mutation可能获取不到commit过来的变量或者结果不对,如下:
    const store = new Vuex.Store({
      state: {
        count: 0,
        list: []
      },
      mutations: {
        increment ({state}, index) {
          // list的内容可能跟你commit时的结果不一样
          state.list= list
          state.count++
        }
      },
      actions: {
        increment ({commit}, payload) {
          // commit时附带payload的属性值
          context.commit('increment', payload.index)
          if (payload.success) payload.success()
        }
      }
    })
    

    在页面中dispatch action:

    this.$store.dispatch("increment", {
        list: [{name: '李白'}, {name: '高渐离'}, {name: '盖聂'}]
        success() {
            alert("incremented!")
        }
    })
    

    因此不要在payload中添加方法属性,不然commit时数据会出错。那么又该怎么实现函数回调呢,vuex官方文档中提供了解决方案:

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

    现在你可以:

    store.dispatch('actionA').then(() => {
      // ...
    })
    

    相关文章

      网友评论

        本文标题:vuex action回调函数

        本文链接:https://www.haomeiwen.com/subject/zrkrjqtx.html