Vuex 核心概念之 Mutation && mapMutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler) 。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const state = {
count: 1
}
const mutation = {
increment (state) {
// 变更状态
state.count++
}
}
// 创建store并暴露store
export const store = new Vuex.Store({
state,
mutations
})
你不能直接调用一个 mutation 处理函数。这个选项更像是事件注册:“当触发一个类型为 increment
的 mutation 时,调用此函数。”要唤醒一个 mutation 处理函数,你需要以相应的 type 调用 store.commit 方法:
store.commit('increment')
提交载荷(Payload)
你可以向 store.commit
传入额外的参数,即 mutation 的载荷(payload) :
mutations: {
increment (state, n) {
state.count += n
}
}
在组件中使用只需:
this.$store.commit('increment', 10)
在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
this.$store.commit('increment', {
amount: 10
})
对象风格的提交方式
提交 mutation 的另一种方式是直接使用包含 type
属性的对象:
this.$store.commit({
type: 'increment',
amount: 10
})
当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此处理函数保持不变:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
使用常量替代 Mutation 事件类型
使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。同时可以把这些常量单独抽离到一个文件中,方便维护
// mutation-types.js
export const INCREMENT = 'increment'
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { INCREMENT } from './mutation-types'
Vue.use(Vuex)
const state = {
count: 1
}
const mutation = {
[INCREMENT](state) {
// 变更状态
state.count++
},
// 或者
INCREMENT(state, payload){
state.count += payload.data
}
}
// 创建store并暴露store
export const store = new Vuex.Store({
state,
mutations
})
用不用常量取决于你——在需要多人协作的大型项目中,这会很有帮助。但如果你不喜欢,你完全可以不这样做。
Mutation 必须是同步函数
由于每一条mutaion
被记录的时候,devtools
都需要捕捉到前一状态和后一状态的快照。假设此时是异步的,devtools
将不知道什么时候异步函数会执行完,将无法对其进行追踪。
mapMutations
首先在组件中提交mutation
可以使用this.$store.commit('xxx')
也可以使用mapMutations
辅助函数将组件中的methods
映射为store.commit
调用
<div>{{$store.state.count}}</div>
<button @click="changeCount(6)">修改count的值</button>
import { mapMutations } from 'vuex'
export default {
methods: {
// 提交mutation的普通写法
changeCount(n){
this.$store.commit({
type: 'INCREMENT',
data: n
})
},
// 借助 mapMutations 生成提交mutations的方法
// 对象写法
// 对象中的key相当于上面的方法名,value相当于type,值会自动传递
...mapMutations[{changeCount: 'INCREMENT'}]
// 数组写法
...mapMutations(['INCREMENT']) // 只需要写mutations中的type即可
}
}