核心提示:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个...
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。mutation 必须是同步函数。
不带载荷
接前面几篇文章的例子,这里我们修改商品价格减半。
store.js
mutations: { // 商品价格减半 goodsPriceDiscount: state => { var goodsPriceDiscount = state.goodsList.map(function(item){ return { price: item.price / 2, name: item.name } }) state.goodsList = goodsPriceDiscount; } }
Page5.vue
要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法。
methods: { // 商品价格减半 discountPrice: function(){ this.$store.commit('goodsPriceDiscount'); }, }
效果图
提交载荷(Payload)
这里修改商品名字。
store.js
// 统一修改商品名字 changeName: (state,payload) => { var changeName = state.goodsList.map(function(item){ return { price: item.price, name: payload // 接收参数 } }) state.goodsList = changeName; }
这里的载荷payload可以是一个对象。
Page6.vue
<p> <h2>我是第二个页面</h2> <p> <input placeholder="请输入新的名字" v-model="input_value" class="input_name" /> <button v-on:click="changeGoodsName">修改商品名字</button> </p> <ul class="ul_list page2"> <li v-for="item in dataList"> <p class="name">商品:{{item.name}}</p> <p class="price">价格:¥{{item.price}}</p> </li> </ul> </p> methods: { // 修改商品名字 changeGoodsName: function(){ this.$store.commit('changeName',this.input_value); }, }
这里的载荷payload就是输入框的值。
效果图
代码执行过程
上面的Mutation执行过程是:按钮点击–>执行按钮点击事件方法–>执行store.commit–>执行mutations里面对应的方法–>修改state里面对应的数据–>页面渲染。
Mutation 需遵守 Vue 的响应规则
既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:
最好提前在你的 store 中初始化好所有所需属性。
当需要在对象上添加新属性时,你应该
使用 Vue.set(obj, 'newProp', 123), 或者
以新对象替换老对象。例如,利用 stage-3 的对象展开运算符我们可以这样写:
state.obj = { ...state.obj, newProp: 123 }