前置篇不会那可不行!Vuex源码学习(六)action和mutation如何被调用的(前置准备篇)
在前置准备篇咱们已经知道被处理好的action与mutation都被集中放置在哪里了。下面就要看dispacth和commit如何去调用它们。vue
commit:segmentfault
首先呢咱们要校订参数,把传入的参数整理下
主要是处理这种形式promise
// 接收一个对象 this.$store.commit({type : 'setName',name : 'xLemon'}); this.$store.commit('setName',{name : 'xLemon'}); 这两个基本等价。 只是第一种方式mutation接收的payload会比第二种多一个type属性, 整理的部分并不关键
type是咱们要找的mutation的名字,如何找到mutation呢?异步
经过 this._mutations[type] 找到要执行的mutation
因此type必定要是mutation的全名函数
因此咱们经过commit找mutation的时候有命名空间的时候就要输入全名,(那种带不少/的)。没有这个名字的mutation容错处理,而后在withCommit函数的包裹下,完成了mutation的执行(全部mutation啊,全名相同的mutation都会被执行)。而后呢遍历_subscribers里面的函数进行执行。学习
_subscribers这是什么?在一开始咱们能够注册一些内容(函数),在commit完成时被通知执行。(观察者模式)如何注册在这一章就很少讲了!后面章节会统一讲述。this
这就是commit作的事情。spa
dispatch呢?code
与commit大同小异,
也有一个_actionSubscribers的属性,在dispatch执行以前所有调用。
对于dispatch Vuex推荐的是放置异步任务,在注册action的时候已经被强制promise化了,因此有多个同名action会经过Promise.all来处理。在action的先后都有对应的钩子函数执行。对象
//在vue组件内一个方法若是屡次使用dispatch和commit,就会很麻烦。 this.$store.dispatch('xxx',payload); this.$store.commit('xxx',payload); const {dispatch,commit} = this.$store; //这至关于建立变量,而后把this.$store的dispatch与commit赋值给它们。 //有经验的都应该知道,函数dispatch和commit的this指向在严格模式下指向undefined。 // 非严格模式下指向window, // 刚才的源码中咱们也看到了,dispatch和commit都依赖于Store实例。怎么办??
解决方法以下:
dispatch和commit是Store原型链上的方法,在constructor内注册了构造函数内的方法,把原型上的dispatch和commit进行了一个this指向的强制绑定,经过call让两个方法永远指向Store的实例上,保证了dispatch和commit不会由于赋值给其他变量等操做致使this指向改变从而发生问题
看一个简单的mutation:
export const setName = function(state,payload) { state.name = payload; };
这个时候不经意间有了一个疑惑?state哪里来的。
这就要从mutation被注册的函数内找缘由了
handle是咱们要被注册的一个mutation,entry是这个同名mutation的容器(存储全部的这个名字的mutation,通常只有一个)在吧handle放入entry的过程当中,
咱们发现,entry是被一个函数包裹起来,而后将local.store和payload绑定到这个handle的参数上,而后把handle的this指向锁定到了Store实例上,因此mutation在被commit调用的时候只传入了一个参数payload,
可是mutation函数执行的时候就有了两个参数。
下面看一下action:
按照刚才的分析action在被dispatch调用的时候会接收一个参数,可是action执行的时候会接收两个参数,第一个参数是个对象里面有六项,真的是一应俱全啊。。。咱们看一下这个对象的六项
{ dispatch : local.dispatch, commit:local.commit, getter: local.getters, state: local.state, rootGetters:store.getters, rootState:store.state }
分为两种一种是local的、一种是store的。mutation中好像也有使用local,那么local的意义是什么呢?咱们下一节会讲述local的含义以及makeLocalContext、makeLocalGetters两个函数的做用。
仍是要给个小线索,在模块树的层级很高的时候,咱们在使用state的时候要一层一层找寻吗?
下一章;离开action与mutation 来讨论一下local的含义以及makeLocalContext、makeLocalGetters两个函数的做用