Vuex store状态的更新唯一方式:提交(commit) mutations
Mutations主要包括两部分:
1.字符串的事件类型(type)
2.一个回调函数,该回调函数的第一个参数就是state,还可以传入第二个参数(mutation的载荷 Payload )
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
counter: 10
},
mutations: {
incrementCount(state, count) {
state.counter += count;
}
}
})
export default store
<template>
<div id="app">
<h2>{{$store.state.counter}}</h2>
<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {}
},
methods:{
addCount(count){
this.$store.commit('incrementCount',count)
}
}
}
</script>
对象风格的提交方式
提交 mutation 的另一种方式是直接使用包含 type 属性的对象:
methods:{
// addCount(count){
// this.$store.commit('incrementCount',count)
// }
//对象风格的提交方式
addCount(count){
this.$store.commit({
type:'incrementCount',
count
})
}
}
注意mutation的第二个参数是对象
mutations: {
// incrementCount(state, count) {
// state.counter += count;
// }
//对象提交风格对应的mutation
incrementCount(state, payload) {
console.log(payload) //{type: "incrementCount", count: 5}
state.counter += payload.count
}
}
使用常量替代 Mutation 事件类型
mutations-types.js
export const INCREMENT_COUNT = 'incrementCount'
App.vue
<template>
<div id="app">
<h2>{{$store.state.counter}}</h2>
<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>
</div>
</template>
<script>
import {INCREMENT_COUNT} from './store/mutations-types'
export default {
name: 'App',
data() {
return {}
},
methods:{
addCount(count){
this.$store.commit(INCREMENT_COUNT,count)
}
}
}
</script>
store
import Vue from 'vue'
import Vuex from 'vuex'
import {
INCREMENT_COUNT
} from './mutations-types'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
counter: 10
},
mutations: {
[INCREMENT_COUNT](state, count) {
state.counter += count
}
}
})
export default store
Mutation 必须是同步函数
如果是异步,当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用,导致无法追踪状态。
<template>
<div id="app">
<h2>{{$store.state.student}}</h2>
<button @click="changeStudent">改变student中的name</button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {}
},
methods:{
changeStudent(){
this.$store.commit('updateStudent')
}
}
}
</script>
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
student: {
age: 18,
name: 'haha'
}
},
mutations: {
updateStudent(state) {
setTimeout(() => {
state.student.name = 'aa'
}, 1000)
}
}
})
export default store
上面的代码 由于mutations里有异步操作,devtools无法追踪,视图上,student对象的name属性
如何处理异步问题?使用actions
mapMutations辅助函数
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
counter: 10
},
mutations:{
increment(state){
state.counter += 1
}
}
})
export default store
<template>
<div id="app">
<h2>{{counter}}</h2>
<button @click="increment">增加</button>
</div>
</template>
<script>
import { mapState,mapMutations } from 'vuex'
export default {
name: 'App',
data () {
return {}
},
computed:{
// 映射 this.myCount 为 this.$store.state.counter
...mapState(['counter'])
},
methods:{
// 将 `this.increment()` 映射为 `this.$store.commit('increment')`
...mapMutations(['increment'])
}
}
</script>
mapMutations也支持对象形式的映射