github的简单实现,blogVuexVuex集中了存储管理应用的所有组件的状态,并使用相应的规则来保证状态以可预测的方式变化。安装Vuexvue添加vuex核心概念state:state,datamutations:functiontochangestateaction:asynchronousoperationstore:containerstate包含以上概念-statestate保存applicationstateexportdefaultnewVuex.Store({state:{counter:0}})
{{$store.state.counter}}
状态改变——突变用于修改状态exportdefaultnewVuex.Store({mutations:{add(state){state.counter++}}})
{{$store.state.counter}}
派生状态-getters从状态派生新状态,类似于计算属性导出默认新Vuex.Store({getters:{doubleCounter(state){returnstate.counter*2;}}})
{{$store.getters.doubleCounter}}
Action-动作添加业务逻辑,类似于controllerexport默认newVuex.Store({actions:{add({commit}){setTimeout(()=>commit('add'),1000);}}})
{{$store.state.counter}}
Vuex原理分析任务分析实现plug-inimplementationStore类维护一个响应状态stateimplementationcommit()implementationdispatch()implementationgettersmount$storecreatenewplugin在Vue2.x项目的src路径下,复制一个store文件,重命名为ou-store。然后在ou-store路径下新建ou-vuex.js文件,将index.js文件中的Vuex介绍改为ou-vuex.js。importVuexfrom'./ou-vuex'修改main.js中router的引入。importrouterfrom'./ou-vuex'创建Vue插件回头看store/index.js,先用Vue.use()注册Vuex,然后实例化Vuex.Store类,所以Vuex对象里面包含安装方法和Store类。importVuefrom'vue'importVuexfrom'vuex'Vue.use(Vuex)exportdefaultnewVuex.Store({...})让我们创建一个新的Vuex插件。让Vue;//保存Vue的构造函数,插件需要使用classStore{}functioninstall(_Vue){Vue=_Vue;}exportdefault{Store,install};挂载$storeletVue;//保存VueConstructor,插件需要使用classStore{}functioninstall(_Vue){Vue=_Vue;Vue.mixin({beforeCreate(){//挂载$storeif(this.$options.store){Vue.prototype.$store=this.$options.store;//vm.$store}}})}export默认{商店,安装};实现状态数据的响应式存储由于状态是一个对象,我们可以使用newVue()将状态转换为响应式数据并保存。其次,我们不能显式保存这个状态暴露给外界,所以可以使用get和set来保存。classStore{/**options:*state*mutations*actions*modules*getters**/constructor(options={}){//数据响应处理this._vm=newVue({data:{$$state:options.state//获取this._vm._data.$$state或this._vm.$data.$$state}});}//获取状态getstate(){returnthis._vm._data.$$state;}//无法设置状态setstate(v){console.error('请使用replaceState重置状态');}}实现commit方法当我们使用commit方法时,就是$store.commit(type,payload),第一个参数是mutations的type值,第二个是payloadload,mutation方法对应的参数是状态和有效载荷,所以让我们实现://保存用户配置的突变选项this._mutations=options.mutations;}getstate(){returnthis._vm._data.$$state;}设置状态(v){console.error('请使用replaceState重置状态');}commit(type,payload){//获取type对应的mutationconstentry=this._mutations[type]if(!entry){console.error(`unknownmutationtype:${type}`);返回;}//将state和payload传递给mutationentry(this.state,payload)}}实现dispatch方法dispatch方法和commit方法类似,不同的是dispatch调用的是action异步函数,action的参数是context和payload,我们可以通过dispatch的参数获取payload,context的执行上下文其实就是实例中的this,但是action是用来处理异步函数的,所以我们需要为dispatch方法Binding实现this;同时,在action方法中可能会调用commit方法,所以我们也需要将this绑定到commit方法上。classStore{constructor(options={}){this._vm=newVue({data:{$$state:options.state}});//保存用户配置的mutations选项和actions选项this._mutations=options.mutations;this._actions=options.actions;//将提交和调度绑定this,this.commit=this.commit.bind(this);this.dispatch=this.dispatch.bind(this);}getstate(){返回this._vm._data.$$state;}setstate(v){console.error('请使用replaceState重置状态');}commit(type,payload){constentry=this._mutations[type]if(!entry){console.error(`unknownmutationtype:${type}`);返回;}entry(this.state,payload)}dispatch(type,payload){//获取用户编写的类型对应的actionconstentry=this._actions[type];if(!entry){console.error(`未知操作类型:${type}`)}//异步结果处理往往需要返回Promisereturnentry(this,payload)}}实现getters派生state我们在定义getters状态的时候,实际上定义了一个函数getters:{doubleCounter(state){returnstate.counter*2;}},在getters中使用派生状态时,实际上得到的是一个值,也就是这个函数的返回值。
doublecount:{{$store.getters.doubleCounter}}
这个其实有点像对象中的get属性,所以我们可以用Object.defineProperty()来实现getter。classStore{constructor(options={}){this._vm=newVue({data:{$$state:options.state}});this._mutations=options.mutations;this._actions=options.actions;这.commit=this.commit.bind(this);this.dispatch=this.dispatch.bind(this);//初始化getter,默认为空对象this.getters={};//遍历options.gettersfor(constkeyinoptions.getters){constself=this;Object.defineProperty(this.getters,key,//键名{get(){//调用对应函数,第一个参数为state,返回结果returnoptions.getters[key](self._vm._data.$$州)}})}}}