目录分析Vuex功能下载模板分析模块结构实现install功能实现Store类替换vuex之前学习了Vuex的概念和使用,做了一个购物车,做一个完整的case,我们来看一个简单的手写的Vuex。分析Vuex的功能首先importvuex是一个对象使用use挂载到Vue实例,use方法调用vuex的install方法调用新的Vuex.Store方法初始化实例传入参数是一个对象,其中包含state,getters,mutations在使用,actions等属性时,直接使用$store.state和$store.getters访问store中的状态,使用getter修改状态。您可以直接使用$store.commit提交变更。在执行异步操作时,您可以使用$store.dispatch分发动作下载。模板vuex-myvuex-demo-temp使用vuex进行简单的模拟操作。这里简单的实现了state、getter、mutations、actions属性,其余的方法没有实现。分析模块结构需要一个vuex模块,这个模块需要导出一个install方法和一个Store类let_Vue=nullclassStore{}//install接收一个参数,Vue的构造函数,Store类后面会用到该构造函数,所以在全局定义一个_Vuefunctioninstall(Vue){_Vue=Vue}exportdefault{Store,install}来实现install函数//install接收一个参数,Vue的构造函数,后面在Store类中使用该构造函数,所以在globalDefinea_Vuefunctioninstall(Vue){_Vue=Vue//1.创建一个Vue实例,将传入的store对象注入到Vue原型上的$store中。你可以在所有组件中使用this.$store来获取Vuex仓库。从而共享状态//2.这里我们获取不到Vue实例,所以这里我们通过混合在beforeCreate中获取Vue实例,从而在option中获取store对象_Vue.mixin({beforeCreate(){//ThishereisVueinstance//首先判断当前Vue实例的options中是否有store,在创建根实例时,会将store注入到Vue实例中,如果是组件实例,没有store选项,所以不需要做这件事}ImplementStoreclassclassStore{//Constructor接收一个参数是一个对象constructor(options){//这里对对象进行了解构,将默认值赋给一个空对象,避免传递当前属性const{state={},getters={},mutations={},actions={}}=options//使状态属性响应this.state=_Vue.observable(state)//处理getters属性//getters是一个对象,对象中有一些方法,这些方法需要接收state参数,最终有返回值,这些方法是获取值,所以可以使用Object.defineProperty将这些方法转化为get访问器//1.首先定义一个this.getters用于直接外部访问,然后将其初始化为一个没有原型对象的空对象this.getters=Object.create(null)//2.遍历所有的getterskey,在this.getters对象中注册对应的key,定义一个get属性,返回key对应的getters中方法的执行结果,传入state对象。keys(getters).forEach(key=>{Object.defineProperty(this.getters,key,{get:()=>getters[key](state)})})//内部属性是私有属性,并且下划线_不期望外部访问//处理mutations属性this._mutations=mutations//处理actions属性this._actions=actions}//在commit方法中获取_mutations//接收两个参数,第一个参数是type,方法名,第二个参数是payLoad,调用方法的参数this.state,payload)}//在dispatch方法中获取_actions//实现方式同commitdispatch(type,payload){//第一个参数是context,这里传入this进行简单模拟,其中包含我们需要的状态,commit等//第二个参数是payloadthis._actions[type](this,payload)}}替换vuex把index.js中vuex的导入替换成../myVuex,打开浏览器,可以看到mutation和动作可以正常执行importVuexfrom'../myVuex'
