Vue 之 Vuex(5)actions 的使用

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
  • mutation 是同步事务

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.statecontext.getters 来获取 state 和 getters。当我们在之后介绍到 Modules 时,你就知道 context 对象为什么不是 store 实例本身了。

DOCTYPE html>
<html lang="en" xmlns="">
<head>
    <meta charset="UTF-8">
    <title>Vuex:actions 的使用title>
head>
<body>
<div id="app">
    <button-counter>button-counter>
div>

<script src="vuex.js">script>
<script src="vue.js">script>
<script>
  Vue.component('ButtonCounter', {
       
    computed: {
       
      ...Vuex.mapState([
        'count'
      ])
    },
    methods: {
       
      increment() {
       
        // 使用 dispatch 触发 actions 下的方法
        this.$store.dispatch('increment')
      },
      ...Vuex.mapActions([
        // 将 `this.incrementAsync(timeout)` 映射为 `this.$store.dispatch('incrementAsync', timeout)`
        'incrementAsync'
      ]),
      ...Vuex.mapActions({
       
        // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
        add: 'increment'
      })
    },
    template: `
      

`
}) // 创建Vuex容器 const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { state.count++ } }, // 异步操作 actions: { // increment(context) { // context.commit('increment') // }, // ES6 简化写法,以上面作用相同 increment({ commit}) { commit('increment') }, // 带有载荷 timeout,载荷可以是 对象,使用方法与 mutations 相同 incrementAsync({ commit}, timeout) { setTimeout(() => { commit('increment') }, timeout) } } }) new Vue({ el: '#app', store });
script> body> html>

复杂一点的例子:

store.js:单独配置 Vuex 容器

import Vue from 'vue'
import Vuex from 'vuex'
import {
     types} from './mutation-types'
import shop from './shop'

Vue.use(Vuex)

// 创建Vuex容器
export default new Vuex.Store({
     
  state: {
     
    cart: {
     
      added: [] // 购物车添加的物品列表
    }
  },
  mutations: {
     
    [types.CHECKOUT_REQUEST](state) {
     
      console.log('清空购物车 ' + state)
    },
    [types.CHECKOUT_SUCCESS](state) {
     
      console.log('购物成功时调用 ' + state)
    },
    [types.CHECKOUT_FAILURE](state, savedCartItems) {
     
      console.log('购物失败时调用 ' + state)
      console.log(savedCartItems)
    },
  },
  // 异步操作
  actions: {
     
    checkout({
      commit, state}, products) {
     
      // 把当前购物车的物品备份起来
      const savedCartItems = [...state.cart.added]
      // 发出结账请求,然后乐观地清空购物车
      commit(types.CHECKOUT_REQUEST)
      // 购物 API 接受一个成功回调和一个失败回调
      setTimeout(() => {
     
        shop.buyProducts(
          products, // 购买的产品
          // 成功操作
          () => commit(types.CHECKOUT_SUCCESS),
          // 失败操作
          () => commit(types.CHECKOUT_FAILURE, savedCartItems)
        )
      }, 2000)
    }
  }
})

mutation-types.js:mutations 方法名称统一管理,有助于项目团队对 state 所包含的 mutations 一目了然

export const types = {
     
  CHECKOUT_REQUEST: 'checkoutRequest',
  CHECKOUT_SUCCESS: 'checkoutSuccess',
  CHECKOUT_FAILURE: 'checkoutFailure',
}

shop:购物类的定义文件

export default function shop() {
     
  // 购买商品 API
  this.buyProducts = function (products, success, failure) {
     
    console.log(products) // 购买的产品
    console.log(success) // 操作成功时调用
    console.log(failure) // 操作失败时调用
  };
}

调用其他异步方法:

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

配合 async/await 使用:

// 假设 getData() 和 getOtherData() 返回的是 Promise

actions: {
     
  async actionC ({
       commit }) {
     
    commit('gotData', await getData())
  },
  async actionD ({
       dispatch, commit }) {
     
    await dispatch('actionC') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

你可能感兴趣的:(vue)