一.什么是mutation
通俗的理解mutations,里面装着一些改变数据方法的集合,这是Veux设计很重要的一点,就是把处理数据逻辑方法全部放在mutations里面,使得数据和视图分离。切记:Vuex中store数据改变的唯一方法就是mutation!
二.怎么用mutations?
1.mutation结构
每一个mutation都有一个字符串类型的事件类型(type)和回调函数(handler),也可以理解为{type:handler()},这和订阅发布有点类似。先注册事件,当触发响应类型的时候调用handker(),调用type的时候需要用到store.commit方法。
//store.js
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
//注册时间,type:increment,handler第一个参数是state;
increment (state) {
// 变更状态
state.count++
}
}
})
//页面上触发
<template>
<button @click="increment">+</button>
</template>
<script>
export default {
methods:{
increment(){
//调用type,触发handler(state)
this.$store.commit('increment');
}
}
}
</script>
2.提交载荷(Payload)
简单的理解就是往handler(state)中传参handler(state,pryload);一般是个对象。
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
store.commit('increment', {
amount: 10
})
3.commit
提交可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
<template>
<div>
<h4>测试1:Count is {{count}}</h4>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script>
export default {
computed:{
count(){
return this.$store.state.count
}
},
methods:{
increment(){
//通过 store.commit 方法触发状态变更(mutation的方法)
this.$store.commit('increment');
},
decrement(){
this.$store.commit('decrement');
}
}
}
</script>
//改成mapMutations 效果是一样
<script>
import { mapMutations } from 'vuex'
export default {
computed:{
count(){
return this.$store.state.count
}
},
methods:{
...mapMutations([
'increment',
'decrement'
])
}
}
</script>
4.使用常量替代 Mutation 事件类型
使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。这样可以使 linter 之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然:
//1.vueDome
<template>
<div>
<h4>测试1:Count is {{count}}</h4>
<button @click="SOME_INCREMENT">+</button>
<button @click="SOME_DECREMENT">-</button>
</div>
</template>
<script>
export default {
computed:{
count(){
return this.$store.state.count
}
},
methods:{
SOME_INCREMENT(){
//通过 store.commit 方法触发状态变更(mutation的方法)
this.$store.commit('SOME_INCREMENT');
},
SOME_DECREMENT(){
this.$store.commit('SOME_DECREMENT');
}
}
}
</script>
//2. mutation-types.js
//使用常量替代 Mutation 事件类型
export const SOME_MUTATION = 'SOME_INCREMENT'
export const SOME_DECREMENT = 'SOME_DECREMENT'
//3.store.js 入口文件vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 引入actions, mutations, getters
import actions from "./actions.js"
import mutations from "./mutations.js"
import getters from "./getters.js"
const state = {
// 应用启动时, count置为0
count:0
}
export default new Vuex.Store({
state,
getters,
actions,
mutations
})
// 4.mutations.js
import { SOME_INCREMENT } from './mutation-types'
import { SOME_DECREMENT } from './mutation-types'
export default {
//使用ES6的箭头函数来给count增值
SOME_INCREMENT:state => state.count ++,
SOME_DECREMENT:state => state.count --,
}
5.Mutation 必须是同步函数
一条重要的原则就是要记住 mutation 必须是同步函数。为什么?请参考下面的例子: