当前位置: 首页 > Web前端 > vue.js

Store构造函数中的Vuexcommit

时间:2023-03-31 19:03:49 vue.js

//将提交和调度绑定到自身conststore=this;const{dispatch,commit}=this;这。dispatch=functionboundDispatch(type,payload){returndispatch.call(store,type,payload)};this.commit=functionboundCommit(type,payload,options){returncommit.call(store,type,payload,options)};const{dispatch,commit}=this其中提交指向Store.prototype.commit;所以其实我们在实例中调用commit的时候,传递的参数经过一层中转,实际上是调用了Store的原型对象的方法,所以我们可以看到$store对象中有一个commit方法,并且__proto__中还有一个commit方法,两者的区别是只传递参数。实际调用的是构造函数原型对象的方法,即$store.__proto__.commit方法。我们一般的commit方法第一个参数是字符串,第二个第一个参数是我们要修改的数据store.commit('increment',{amount:10})官方文档也提供了一种方式:object-style提交方式另一种提交mutation的方式是直接使用type属性Object:store.commit({type:'increment',amount:10})为什么可以这样调用呢?我们粗略看一下原型对象的commit方法const突变={类型,有效载荷};constentry=this._mutations[type];if(!entry){{console.error(`[vuex]未知变异类型:${type}`);}return}this._withCommit(()=>{entry.forEach(functioncommitIterator(handler){handler(payload);});});this._subscribers.forEach(sub=>sub(mutation,this.state));if(options&&options.silent){console.warn(`[vuex]mutationtype:${type}.Silent选项已被删除。`+'使用vue-devtools中的过滤器功能');}}调用commit方法时使用unifyObjectStyle方法是将两个参数转换成相同的格式使用functionunifyObjectStyle(type,payload,options){if(isObject(type)&&type.type){options=payload;有效载荷=类型;type=type.type;}{assert(typeoftype==='string',`预期字符串为类型,但发现${typeoftype}。`);}return{type,payload,options}}最终返回的对象类型为字符串,payload的意思是,如果以object样式提交加载,转换后和我们正常提交加载格式一样。期权的作用还不了解,暂时无法分析。接下来看constentry=this._mutations[type];这里的_mutations将我们写在store对象中的mutations以数组的形式存储起来,存储在_mutations对象对应的value中。例如,在{mutations:{addCount(state,payload){state.count=state.count+1;}}}然后this._mutations('addCount')指向一个数组,数组中有一个addCount方法。this._withCommit(()=>{entry.forEach(functioncommitIterator(handler){handler(payload);});});那么在调用的时候,使用forEach遍历数据,然后执行loadpayload到handler中,为什么呢?调用_withCommit中的方法怎么样,_withCommit(fn){constcommitting=this._committing;this._committing=true;fn();this._committing=提交;}提交时设置this._committing为true,待执行完fn后,设置this._commiting=committing。这里要注意一点,fn函数必须是同步函数,这样才能保证fn方法执行完后,再将this._committing设置为false,这也是为什么官方文档会提到mutation-mustbeasynchronousfunction。因为触发突变时回调函数还没有被调用,devtools不知道回调函数真正被调用的时间——本质上,回调函数中所做的任何状态变化都是无法追踪的所以这个_committing函数的作用是什么enableStrictMode(store){store._vm.$watch(function(){returnthis._data.$$state},()=>{{assert(store._committing,`不要在突变处理程序之外改变vuex存储状态。`);}},{deep:true,sync:true});}通过这段代码的提示,大概可以推断出它的作用。当store的数据被修改时,就会触发上面的代码。如果通过commit方法修改了数据,此时_committing为true,而如果直接修改store上的数据,此时_committing仍然为false,我们可以通过_committing判断是否被commit修改旗帜。官方文档说在Vuexstore中改变状态的唯一方法是提交一个mutation。这实际上只是一个约定。只有这样,才能在突变中发现所有的数据变化,才能完善。.