Vuex Mutation介绍
发布时间:2023-04-04 08:45:19 所属栏目:教程 来源:
导读:Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const s
const s
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数: const store = new Vuex.Store({ state: { count: }, mutations: { increment (state) { // 变更状态 state.count++ } } }) 我们不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。” 要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法: store.commit('increment') 你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload): mutations: { incrementByCount (state, n) { state.count = state.count + n } } store.commit('incrementByCount', ) 在大多数情况下,载荷应该是一个对象,我们通常接收的参数命名为 payload,这样可以包含多个字段并且记录的 mutation 会更易读: // 定义 mutation mutations: { incrementByCount (state, payload) { state.count = state.count + payload.count } } // 触发 mutation store.commit('incrementByCount', { count: }) 提交 mutation 的另一种方式是直接使用包含 type 属性的对象: store.commit({ type: 'incrementByCount', count: }) 当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此 handler 保持不变: mutations: { incrementByCount (state, payload) { state.count = state.count + payload.count } } 完整示例: <!DOCTYPE html> <html lang="en"> <head> <Meta charset="UTF-8"> <Meta name="viewport" content="width=device-width, initial-scale=1.0"> <Meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <div>购物车数量:{{count}}</div> <button @click="add">无参 mutation(+1)</button> <button @click="addTen">携参 mutation(+10)</button> <button @click="addByObject">携带对象类型的参数 mutation(+5)</button> <button @click="commitByObject">对象类型提交 mutation(+3)</button> </div> </body> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vuex@3.1.2/dist/vuex.js"></script> <script type="text/javascript"> const store = new Vuex.Store({ state: { count: }, mutations: { // 无参 mutation increment(state) { state.count++ }, // 带参 mutation incrementByCount(state, count) { state.count = state.count + count }, // 对象类型参数 mutation incrementByObject(state, payload) { state.count = state.count + payload.count }, }, }) var vm = new Vue({ el: '#app', store, methods: { add() { this.$store.commit('increment') }, addTen() { this.$store.commit('incrementByCount', ) }, addByObject() { this.$store.commit('incrementByObject', { count: }) }, commitByObject() { this.$store.commit( { type: 'incrementByObject', count: }) } }, computed: { count() { return this.$store.state.count } } }) </script> </html> 代码解释 JS 代码第 9-11 行,定义了一个无参的 mutation,对 state.count + 1。 JS 代码第 12-14 行,定义一个传入 Number 类型参数 count 的 mutation,对 state.count + count。 JS 代码第 16-18 行,定义一个传入 Object 类型参数 payload 的 mutation,对 state.count + payload.count。 JS 代码第 26 行,提交 mutation increment。 JS 代码第 28 行,提交 mutation incrementByCount 并传入数量 10。 JS 代码第 31-33 行,提交 mutation incrementByObject 并传入参数 {count: 5}。 JS 代码第 36-39 行,以对象的形式提交 mutation incrementByObject。 既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守以下注意事项: 最好提前在你的 store 中初始化好所有所需属性。 当需要在对象上添加新属性时,你应该: 使用 Vue.set (obj, ‘newProp’, 123), 或者 以新对象替换老对象。例如,利用对象展开运算符我们可以这样写: state.obj = { ...state.obj, newProp: } Tips:以新对象替换老对象替换老对象的方式只能修改 state 中的某个属性,而不能替换整个 state。想要替换整个 state,需要使用 store.replaceState () 的方法: state.obj = { ...state.obj, newProp: } // OK state = {...state, name: '123'} // Error store.replaceState({...state, name: '123'}) // OK 在日常开发中,我们一般会使用常量替代 mutation 事件类型。这样可以使 linter 之类的工具发挥作用,同时可以让你的代码合作者对整个 app 包含的 mutation 一目了然: const INCREMENT_COUNT = 'INCREMENT_COUNT' const store = new Vuex.Store({ state: { count: }, mutations: { [INCREMENT_COUNT](state) { state.count++ }, }, }) var vm = new Vue({ el: '#app', store, methods: { add() { this.$store.commit('INCREMENT_COUNT') }, } }) 当然,是否使用用常量取决于个人喜好 —— 在需要多人协作的大型项目中,这会很有帮助。但如果你不喜欢,你完全可以不这样做。 (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |