Action 类似于 mutation,不同在于:
Action 函数接受一个与 store 实例具有相同方法和属性的 context
对象,因此你可以调用 context.commit
提交一个 mutation,或者通过 context.state
和 context.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())
}
}