Vuex Mutation
每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})以相应的 type 调用 store.commit 方法:
store.commit('increment')提交载荷(Payload)
向 store.commit 传入额外的参数 :载荷(payload)
// ...
mutations: {
increment (state, n) {
state.count += n
}
}调用:
store.commit('increment', 10)载荷是一个对象时:
// ...
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}调用:
store.commit('increment', {
amount: 10
})对象风格:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}调用:
store.commit({
type: 'increment',
amount: 10
})其他规则:
最好提前在你的 store 中初始化好所有所需属性。
当需要在对象上添加新属性时,你应该
使用
Vue.set(obj, 'newProp', 123), 或者以新对象替换老对象。例如,利用对象展开运算符我们可以这样写:
state.obj = { ...state.obj, newProp: 123 }
使用常量替代 Mutation 事件类型
// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
state: { ... },
mutations: {
// 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
[SOME_MUTATION] (state) {
// mutate state
}
}
})
Mutation 必须是同步函数
index.jsimport Vue from 'vue';
import 'es6-promise/auto'
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0,
countPlus: 1,
countLength: 1,
productName: '',
productPrice: 0,
productTotal: 0,
},
getters: {
countCache: function (state) {
return state.count + state.countPlus;
},
countFunc: function (state) {
return function (num) {
return state.countPlus > num;
}
}
},
mutations: {
increment(state) {
state.count++;
state.countPlus = state.count + 1;
state.countLength = state.count.toString().length;
},
decrement(state) {
state.count--;
state.countPlus = state.count + 1;
state.countLength = state.count.toString().length;
},
calculate(state, payload) {
state.productPrice = payload.price;
state.productName = payload.name;
state.productTotal = state.productPrice * state.count;
},
},
});
export default store;
StoreComponent.vue:
<template> <div> <button @click="increment"> {{count}}</button> <button @click="decrement"> {{count}}</button> <span> Plus one: {{ countPlus }}</span> <span> Length: {{ countLength}}</span> <span> Plus one Length: {{ countPlusLength}}</span> <span> countAndCountPlusCache: {{ countPCountPlusCache}}</span> <span> countAndCountPlusFunc: {{ countPCountPlusFunc}}</span> <div> <span> countCache: {{ countCa}}</span> <span> countFunc: {{ countFu(12)}}</span> </div> <div> <table> <tr> <th>Product Name</th> <th>Product Count</th> <th>Product Price</th> <th>Product Total</th> </tr> <tr> <th>{{pName}}</th> <th>{{count}}</th> <th>{{pPrice}}</th> <th>{{pTotal}}</th> </tr> </table> </div> <div> <input type="text" v-model="productName"> <input type="text" v-model="productPrice"> <button @click="calculate">Calculate</button> </div> </div> </template> <script> import {mapState} from 'vuex'; import {mapGetters} from 'vuex'; export default { name: "StoreComponent", data: function () { return { productName: '', productPrice: 0, } }, // computed: { // count() { // return this.$store.state.count; // }, // // }, computed: { countPlusLength() { return this.countPlus.toString().length; }, countPCountPlusCache() { return this.$store.getters.countCache; }, countPCountPlusFunc() { return this.$store.getters.countFunc(2); }, ...mapState({ count: state => state.count, countPlus: 'countPlus', countLength(state) { return state.countLength; }, pName: 'productName', pPrice: 'productPrice', pTotal: 'productTotal', }), // 使用对象展开运算符将 getter 混入 computed 对象中 // ...mapGetters([ // 'countCache', // 'countFunc', // ]), ...mapGetters({ // 把 `this.countCa` 映射为 `this.$store.getters.countCache` countCa: 'countCache', // 把 `this.countFu` 映射为 `this.$store.getters.countFunc` countFu: 'countFunc', }), }, // computed: mapState([ // 'count', // 'countPlus', // 'countLength', // ]), methods: { increment() { this.$store.commit('increment'); }, decrement() { this.$store.commit('decrement'); }, calculate() { let payload = { price: this.productPrice, name: this.productName, }; // this.$store.commit('calculate', payload); // this.$store.commit({ // type: 'calculate', // price: this.productPrice, // name: this.productName, // }); }, } } </script> <style scoped> </style>
效果:
mapMutations 辅助函数
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}StoreComponent.vue:
<template> <div> <button @click="increment"> {{count}}</button> <button @click="decrement"> {{count}}</button> <span> Plus one: {{ countPlus }}</span> <span> Length: {{ countLength}}</span> <span> Plus one Length: {{ countPlusLength}}</span> <span> countAndCountPlusCache: {{ countPCountPlusCache}}</span> <span> countAndCountPlusFunc: {{ countPCountPlusFunc}}</span> <div> <span> countCache: {{ countCa}}</span> <span> countFunc: {{ countFu(12)}}</span> </div> <div> <table> <tr> <th>Product Name</th> <th>Product Count</th> <th>Product Price</th> <th>Product Total</th> </tr> <tr> <th>{{pName}}</th> <th>{{count}}</th> <th>{{pPrice}}</th> <th>{{pTotal}}</th> </tr> </table> </div> <div> <input type="text" v-model="productName"> <input type="text" v-model="productPrice"> <button @click="calculate({ type: 'calculate', price: productPrice, name: productName,})">Calculate </button> </div> </div> </template> <script> import {mapState} from 'vuex'; import {mapGetters} from 'vuex'; import {mapMutations} from 'vuex'; export default { name: "StoreComponent", data: function () { return { productName: '', productPrice: 0, } }, // computed: { // count() { // return this.$store.state.count; // }, // // }, computed: { countPlusLength() { return this.countPlus.toString().length; }, countPCountPlusCache() { return this.$store.getters.countCache; }, countPCountPlusFunc() { return this.$store.getters.countFunc(2); }, ...mapState({ count: state => state.count, countPlus: 'countPlus', countLength(state) { return state.countLength; }, pName: 'productName', pPrice: 'productPrice', pTotal: 'productTotal', }), // 使用对象展开运算符将 getter 混入 computed 对象中 // ...mapGetters([ // 'countCache', // 'countFunc', // ]), ...mapGetters({ // 把 `this.countCa` 映射为 `this.$store.getters.countCache` countCa: 'countCache', // 把 `this.countFu` 映射为 `this.$store.getters.countFunc` countFu: 'countFunc', }), }, // computed: mapState([ // 'count', // 'countPlus', // 'countLength', // ]), methods: { increment() { this.$store.commit('increment'); }, decrement() { this.$store.commit('decrement'); }, // calculate() { // let payload = { // price: this.productPrice, // name: this.productName, // }; // // this.$store.commit('calculate', payload); // // // this.$store.commit({ // // type: 'calculate', // // price: this.productPrice, // // name: this.productName, // // }); // }, ...mapMutations([ 'calculate', ]), } } </script> <style scoped> </style>
效果:



浙公网安备 33010602011771号